2-stage asynchronous starting of a download

This commit is contained in:
Veloman Yunkan 2024-06-26 12:41:55 +04:00 committed by Kelson
parent 07d8aff798
commit b5b089f9a6
4 changed files with 32 additions and 8 deletions

View File

@ -525,16 +525,36 @@ void ContentManager::downloadBook(const QString &id)
return;
}
startDownload(id);
mp_library->addBookBeingDownloaded(book, downloadPath);
mp_library->save();
DownloadManager::addRequest(DownloadState::START, id);
const auto downloadState = DownloadManager::getDownloadState(id);
managerModel->setDownloadState(id, downloadState);
}
// This function is called asynchronously in a worker thread processing all
// download operations. The call is initiated in downloadBook().
void ContentManager::startDownload(QString id)
{
kiwix::Book book = getRemoteOrLocalBook(id);
const auto downloadPath = getSettingsManager()->getDownloadDir();
// downloadPath may be different from the value used in
// downloadBook(). This may happen in the following scenario:
//
// 1. aria2c is stuck because of having to save to
// slow storage (and the fact that it is a single-threaded
// application). This may result in startDownload() being
// called with significant delay after downloadBook().
//
// 2. The user changes the download directory after starting
// a download.
//
// That's why the checkThatBookCanBeDownloaded() check is repeated here.
std::string downloadId;
try {
DownloadManager::checkThatBookCanBeDownloaded(book, downloadPath);
downloadId = DownloadManager::startDownload(book, downloadPath);
} catch ( const KiwixAppError& err ) {
emit error(err.summary(), err.details());
@ -544,8 +564,6 @@ void ContentManager::startDownload(QString id)
book.setDownloadId(downloadId);
mp_library->addBookBeingDownloaded(book, downloadPath);
mp_library->save();
const auto downloadState = DownloadManager::getDownloadState(id);
managerModel->setDownloadState(id, downloadState);
emit(oneBookChanged(id));
}

View File

@ -119,7 +119,7 @@ private: // functions
const kiwix::Book& getRemoteOrLocalBook(const QString &id);
QString getRemoteLibraryUrl() const;
void startDownload(QString bookId);
void startDownload(QString bookId) override;
void removeDownload(QString bookId);
void downloadDisappeared(QString bookId);
void downloadCompleted(QString bookId, QString path);

View File

@ -131,7 +131,7 @@ void DownloadManager::processDownloadActions()
const Request req = m_requestQueue.dequeue();
if ( !req.bookId.isEmpty() ) {
switch ( req.action ) {
case DownloadState::START: /* startDownload(req.bookId); */ break; // API problem
case DownloadState::START: startDownload(req.bookId); break;
case DownloadState::PAUSE: pauseDownload(req.bookId); break;
case DownloadState::RESUME: resumeDownload(req.bookId); break;
case DownloadState::CANCEL: cancelDownload(req.bookId); break;
@ -280,12 +280,15 @@ std::string DownloadManager::startDownload(const kiwix::Book& book, const QStrin
} catch (std::exception& e) {
throwDownloadUnavailableError();
}
m_downloads.set(bookId, std::make_shared<DownloadState>());
return downloadId;
}
void DownloadManager::addRequest(Action action, QString bookId)
{
if ( action == DownloadState::START ) {
m_downloads.set(bookId, std::make_shared<DownloadState>());
}
if ( const auto downloadState = getDownloadState(bookId) ) {
m_requestQueue.enqueue({action, bookId});
if ( action != DownloadState::UPDATE ) {

View File

@ -160,8 +160,6 @@ public: // functions
// successful download
void checkThatBookCanBeDownloaded(const kiwix::Book& book, const QString& downloadDirPath);
// returns the download id
std::string startDownload(const kiwix::Book& book, const QString& downloadDirPath);
void removeDownload(QString bookId);
DownloadStatePtr getDownloadState(QString bookId) const
@ -175,6 +173,10 @@ signals:
void downloadCancelled(QString bookId);
void downloadDisappeared(QString bookId);
protected:
// returns the download id
std::string startDownload(const kiwix::Book& book, const QString& downloadDirPath);
private: // types
struct Request
{
@ -190,6 +192,7 @@ private: // types
private: // functions
void processDownloadActions();
virtual void startDownload(QString bookId) = 0;
void pauseDownload(const QString& bookId);
void resumeDownload(const QString& bookId);
void updateDownload(QString bookId);