Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 4486408

Browse files
authored
Merge pull request #1542 from janhq/j/update-download-percentage-event
fix: incorrect downloadedBytes callback
2 parents 64b1d1e + f0f1e99 commit 4486408

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

engine/services/download_service.cc

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ cpp::result<bool, std::string> DownloadService::Download(
228228

229229
curl_off_t DownloadService::GetLocalFileSize(
230230
const std::filesystem::path& path) const {
231-
FILE* file = fopen(path.string().c_str(), "r");
231+
auto file = fopen(path.string().c_str(), "r");
232232
if (!file) {
233233
return -1;
234234
}
@@ -237,7 +237,7 @@ curl_off_t DownloadService::GetLocalFileSize(
237237
return -1;
238238
}
239239

240-
curl_off_t file_size = ftell64(file);
240+
auto file_size = ftell64(file);
241241
fclose(file);
242242
return file_size;
243243
}
@@ -264,11 +264,7 @@ void DownloadService::ProcessTask(DownloadTask& task) {
264264
CTL_INF("Processing task: " + task.id);
265265
std::vector<std::pair<CURL*, FILE*>> task_handles;
266266

267-
downloading_data_ = std::make_shared<DownloadingData>(DownloadingData{
268-
.item_id = "",
269-
.download_task = &task,
270-
.event_queue = event_queue_.get(),
271-
});
267+
active_task_ = std::make_shared<DownloadTask>(task);
272268

273269
for (auto& item : task.items) {
274270
CURL* handle = curl_easy_init();
@@ -284,7 +280,13 @@ void DownloadService::ProcessTask(DownloadTask& task) {
284280
CTL_ERR("Failed to open output file " + item.localPath.string());
285281
return;
286282
}
287-
downloading_data_->item_id = item.id;
283+
284+
auto dl_data_ptr = std::make_shared<DownloadingData>(DownloadingData{
285+
.item_id = item.id,
286+
.download_service = this,
287+
});
288+
downloading_data_map_.insert(std::make_pair(item.id, dl_data_ptr));
289+
288290
if (auto headers = CreateHeaders(item.downloadUrl); headers) {
289291
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
290292
}
@@ -294,7 +296,7 @@ void DownloadService::ProcessTask(DownloadTask& task) {
294296
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
295297
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);
296298
curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, ProgressCallback);
297-
curl_easy_setopt(handle, CURLOPT_XFERINFODATA, downloading_data_.get());
299+
curl_easy_setopt(handle, CURLOPT_XFERINFODATA, dl_data_ptr.get());
298300

299301
curl_multi_add_handle(multi_handle_, handle);
300302
task_handles.push_back(std::make_pair(handle, file));
@@ -329,6 +331,8 @@ void DownloadService::ProcessTask(DownloadTask& task) {
329331
fclose(pair.second);
330332
}
331333

334+
active_task_.reset();
335+
downloading_data_map_.clear();
332336
return;
333337
}
334338

@@ -338,7 +342,8 @@ void DownloadService::ProcessTask(DownloadTask& task) {
338342
curl_easy_cleanup(pair.first);
339343
fclose(pair.second);
340344
}
341-
downloading_data_.reset();
345+
downloading_data_map_.clear();
346+
active_task_.reset();
342347

343348
RemoveTaskFromStopList(task.id);
344349

engine/services/download_service.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ class DownloadService {
8080
private:
8181
struct DownloadingData {
8282
std::string item_id;
83-
DownloadTask* download_task;
84-
EventQueue* event_queue;
83+
DownloadService* download_service;
8584
};
8685

8786
cpp::result<void, std::string> VerifyDownloadTask(
@@ -113,7 +112,9 @@ class DownloadService {
113112
callbacks_;
114113
std::mutex callbacks_mutex_;
115114

116-
std::shared_ptr<DownloadingData> downloading_data_;
115+
std::shared_ptr<DownloadTask> active_task_;
116+
std::unordered_map<std::string, std::shared_ptr<DownloadingData>>
117+
downloading_data_map_;
117118

118119
void WorkerThread();
119120

@@ -131,13 +132,23 @@ class DownloadService {
131132

132133
static int ProgressCallback(void* ptr, curl_off_t dltotal, curl_off_t dlnow,
133134
curl_off_t ultotal, curl_off_t ulnow) {
134-
auto* downloading_data = static_cast<DownloadingData*>(ptr);
135-
auto& event_queue = *downloading_data->event_queue;
136-
auto& download_task = *downloading_data->download_task;
135+
auto downloading_data = static_cast<DownloadingData*>(ptr);
136+
if (downloading_data == nullptr) {
137+
return 0;
138+
}
139+
const auto dl_item_id = downloading_data->item_id;
140+
if (dltotal <= 0) {
141+
return 0;
142+
}
143+
144+
auto dl_srv = downloading_data->download_service;
145+
auto active_task = dl_srv->active_task_;
146+
if (active_task == nullptr) {
147+
return 0;
148+
}
137149

138-
// update the download task with corresponding download item
139-
for (auto& item : download_task.items) {
140-
if (item.id == downloading_data->item_id) {
150+
for (auto& item : active_task->items) {
151+
if (item.id == dl_item_id) {
141152
item.downloadedBytes = dlnow;
142153
item.bytes = dltotal;
143154
break;
@@ -154,10 +165,10 @@ class DownloadService {
154165

155166
// throttle event by 1 sec
156167
if (time_since_last_event >= 1000) {
157-
event_queue.enqueue(
168+
dl_srv->event_queue_->enqueue(
158169
EventType::DownloadEvent,
159170
DownloadEvent{.type_ = DownloadEventType::DownloadUpdated,
160-
.download_task_ = download_task});
171+
.download_task_ = *active_task});
161172

162173
// Update the last event time
163174
last_event_time = current_time;

0 commit comments

Comments
 (0)