Checkpoint
This commit is contained in:
+127
-27
@@ -22,6 +22,10 @@
|
||||
*/
|
||||
|
||||
#include "Tone3000DownloaderImpl.hpp"
|
||||
#include "Tone3000DownloadProgress.hpp"
|
||||
#include "Tone3000Download.hpp"
|
||||
#include "Uri.hpp"
|
||||
#include <functional>
|
||||
|
||||
using namespace pipedal;
|
||||
|
||||
@@ -67,9 +71,10 @@ Tone3000DownloaderImpl::handle_t Tone3000DownloaderImpl::RequestDownload(
|
||||
|
||||
this->requestQueue.push_back(request);
|
||||
request = nullptr;
|
||||
if (!this->thread)
|
||||
if (!this->thread)
|
||||
{
|
||||
this->thread = std::make_unique<std::jthread>([this]{ this->ThreadProc(); });
|
||||
this->thread = std::make_unique<std::jthread>([this]
|
||||
{ this->ThreadProc(); });
|
||||
}
|
||||
}
|
||||
this->thread_cv.notify_one();
|
||||
@@ -97,7 +102,8 @@ void Tone3000DownloaderImpl::CancelDownload(
|
||||
}
|
||||
}
|
||||
|
||||
void Tone3000DownloaderImpl::Close() {
|
||||
void Tone3000DownloaderImpl::Close()
|
||||
{
|
||||
bool notify = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard{this->mutex};
|
||||
@@ -109,7 +115,7 @@ void Tone3000DownloaderImpl::Close() {
|
||||
|
||||
this->requestQueue.resize(0);
|
||||
|
||||
DownloadProgress progress;
|
||||
Tone3000DownloadProgress progress;
|
||||
fgDownloadProgress = progress;
|
||||
|
||||
if (listener)
|
||||
@@ -121,12 +127,14 @@ void Tone3000DownloaderImpl::Close() {
|
||||
activeRequest->cancelled = true;
|
||||
}
|
||||
}
|
||||
if (notify) {
|
||||
if (notify)
|
||||
{
|
||||
thread_cv.notify_one();
|
||||
}
|
||||
}
|
||||
Tone3000DownloaderImpl::DownloadProgress Tone3000DownloaderImpl::GetDownloadStatus() {
|
||||
DownloadProgress result;
|
||||
Tone3000DownloadProgress Tone3000DownloaderImpl::GetDownloadStatus()
|
||||
{
|
||||
Tone3000DownloadProgress result;
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard{this->mutex};
|
||||
result = fgDownloadProgress;
|
||||
@@ -134,47 +142,139 @@ Tone3000DownloaderImpl::DownloadProgress Tone3000DownloaderImpl::GetDownloadStat
|
||||
return result;
|
||||
}
|
||||
|
||||
void Tone3000DownloaderImpl::bgUpdateDownloadProgress(const DownloadProgress &progress)
|
||||
void Tone3000DownloaderImpl::bgUpdateDownloadProgress(const Tone3000DownloadProgress &progress)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard{this->mutex};
|
||||
if (closed)
|
||||
if (closed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->fgDownloadProgress = progress;
|
||||
if (listener)
|
||||
if (activeRequest != nullptr && !activeRequest->cancelled)
|
||||
{
|
||||
listener->OnTone3000Progress(this->fgDownloadProgress);
|
||||
this->fgDownloadProgress = progress;
|
||||
if (listener)
|
||||
{
|
||||
listener->OnTone3000Progress(this->fgDownloadProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Tone3000DownloaderImpl::PerformDownload(
|
||||
const std::string &downloadPath,
|
||||
const std::string &downloadUrl,
|
||||
int64_t downloadHandle,
|
||||
std::function<bool()> isCancelled)
|
||||
{
|
||||
std::string downloadedDirectory;
|
||||
// Validate Tone3000 URL
|
||||
uri downloadUri{downloadUrl};
|
||||
if (!downloadUri.authority().ends_with(".tone3000.com"))
|
||||
{
|
||||
throw std::runtime_error("Invalid Tone3000 URL address.");
|
||||
}
|
||||
|
||||
// Check for cancellation before starting
|
||||
if (isCancelled())
|
||||
{
|
||||
return downloadedDirectory;
|
||||
}
|
||||
|
||||
Tone3000DownloadProgress progress;
|
||||
this->bgUpdateDownloadProgress(progress);
|
||||
// Perform the download using existing code
|
||||
downloadedDirectory = tone3000::DownloadTone3000Bundle(
|
||||
downloadPath,
|
||||
downloadUrl,
|
||||
downloadHandle,
|
||||
[this](const Tone3000DownloadProgress &progress)
|
||||
{
|
||||
this->bgUpdateDownloadProgress(progress);
|
||||
},
|
||||
[isCancelled]()
|
||||
{
|
||||
return isCancelled();
|
||||
});
|
||||
|
||||
// Check for cancellation after download
|
||||
if (isCancelled())
|
||||
{
|
||||
// maybe there's a partial result.
|
||||
return downloadedDirectory;
|
||||
}
|
||||
return downloadedDirectory;
|
||||
}
|
||||
|
||||
void Tone3000DownloaderImpl::ThreadProc()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
std::shared_ptr<DownloadRequest> downloadRequest;
|
||||
std::shared_ptr<DownloadRequest> request;
|
||||
Listener *currentListener = nullptr;
|
||||
|
||||
Tone3000DownloadProgress progress;
|
||||
|
||||
{
|
||||
std::unique_lock lock { this->mutex};
|
||||
this->activeRequest = nullptr;
|
||||
std::unique_lock<std::mutex> lock{this->mutex};
|
||||
thread_cv.wait(lock, [this]()
|
||||
{ return this->closed || this->requestQueue.size() != 0; });
|
||||
|
||||
this->thread_cv.wait(lock,[this] { return this->closed || this->requestQueue.size() != 0;});
|
||||
|
||||
if (this->closed) {
|
||||
if (closed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this->requestQueue.size() != 0)
|
||||
|
||||
if (requestQueue.empty())
|
||||
{
|
||||
this->activeRequest = this->requestQueue[0];
|
||||
this->requestQueue.erase(requestQueue.begin());
|
||||
continue;
|
||||
}
|
||||
downloadRequest = this->activeRequest;
|
||||
}
|
||||
if (!downloadRequest)
|
||||
{
|
||||
continue;
|
||||
|
||||
// Dequeue the next request
|
||||
request = requestQueue.front();
|
||||
requestQueue.erase(requestQueue.begin());
|
||||
activeRequest = request;
|
||||
currentListener = listener;
|
||||
}
|
||||
|
||||
|
||||
// Notify download started
|
||||
if (currentListener)
|
||||
{
|
||||
currentListener->OnStartTone3000Download(request->handle, request->downloadUrl);
|
||||
}
|
||||
|
||||
// Create cancellation predicate that checks the atomic flag
|
||||
auto isCancelled = [request]() -> bool
|
||||
{
|
||||
return request->cancelled.load();
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
std::string outputPath = PerformDownload(request->downloadPath, request->downloadUrl, request->handle, isCancelled);
|
||||
|
||||
// Notify completion if not cancelled
|
||||
{
|
||||
std::lock_guard lockGuard{mutex};
|
||||
if (!request->cancelled.load() && currentListener)
|
||||
{
|
||||
currentListener->OnTone3000DownloadComplete(request->handle,outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
{
|
||||
std::lock_guard lockGuard{mutex};
|
||||
// Notify error
|
||||
if (!request->cancelled.load() && currentListener)
|
||||
{
|
||||
currentListener->OnTone3000DownloadError(request->handle, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{this->mutex};
|
||||
activeRequest = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user