修复SpkDownloadMgr重大bug

1. 原有依靠Qt Network的连接超时不可靠,改为自己使用Watchdog值跟踪。
2. 原有代码在请求时大量未对Reply设置正确的workerId,已修正
3. 原有代码不能自动在出错worker出错但其他worker已经全部完成时进行得分配,已修正
4. 原有代码ActiveWorkerCount计算方法不准确,每次link都会增加,但是由于重试重分配都会Link而且Worker不会从
List中删除,所以已改为任务开始时一次加满
5. 原有代码忘记在WorkerFinish时检查有否未写入的cache以及未关闭下载文件
6. 原有代码未将Reply的errorOccurred信号与WorkerError槽连接,导致这个槽并没有发挥什么卵用

测试文件改为有道词典,小一点
增加了等待HEAD请求时光标变成忙的特性
This commit is contained in:
RigoLigoRLC
2022-02-19 02:38:03 +08:00
parent 03f157f620
commit 8f32141726
4 changed files with 83 additions and 5 deletions

View File

@@ -7,6 +7,9 @@
/**
* @note SpkDownloadMgr does NOT do download scheduling and other things; it's only a multithreaded
* downloader; it manages the threads that are downloading stuff from the Internet.
*
* Because of this, SpkDownloadMgr does not support complex download queues, cannot handle
* pauses, and can only work on a sequential list of tasks.
*/
class SpkDownloadMgr : public QObject
@@ -34,15 +37,22 @@ class SpkDownloadMgr : public QObject
* unnecessary race conditions and data safety problems.
* DownloadWorker is also used in mFailureRetryQueue to indicate the blocks that needed
* to be retried on other servers.
*
* Each worker has a watch dog value, incremented each time the download speed is
* updated, and zeroed each time the worker has data ready. If the value exceeds a
* preset maximum, then this worker is considered timed out and killed.
*/
struct DownloadWorker
{
QNetworkReply *Reply; ///< Reply from the network
int Watchdog; ///< Watch dog value watching for a timed out worker
qint64 BeginOffset; ///< Where should a worker start downloading
qint64 BytesNeeded; ///< How many bytes a worker should fetch in total
qint64 BytesRecvd; ///< How many bytes a worker has received till now
};
constexpr static int WatchDogMaximum = 7;
struct RemoteFileInfo
{
qint64 Size = -1;