Use fresh WebClient for fallback URLs #2539
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Sometimes when downloading mods, CKAN indicates negative bytes remaining and greater than 100% progress towards completion. This problem has been reported on both CmdLine and GUI, and presumably ConsoleUI would be affected as well:
Cause
When the primary download URL for a redistributable mod fails, we fall back to its
archive.org
URL as of #2284. This is done by callingagent.DownloadFileAsync
in theagent.DownloadFileCompleted
event handler when it indicates failure. Notably this re-uses the sameWebClient
object.Since the negative bytes remaining and greater than 100% progress numbers come directly from values provided by
WebClient
, I think theWebClient
object is getting corrupted by this sequence of events. It may not be prepared for us to initiate a new download while the previous one is still being dealt with.Changes
NetAsyncDownloaderDownloadPart
'sWebClient
object is now changed frompublic
toprivate
. Small wrapper functions and events are added to handle the operations that this object performs, andNetAsyncDownloader
is updated to call them:Download
- Replacesagent.DownloadFileAsync
Abort
- Replacesagent.CancelAsync
Progress
- Replacesagent.DownloadProgressChanged
Done
- Replacesagent.DownloadFileCompleted
This encapsulation allows
NetAsyncDownloaderDownloadPart.Download
to ensure that itsWebClient
object is replaced and re-initialized before any download operation. Rather than re-using a potentially scrambled object, fallback URLs will now have their own freshWebClient
.Should fix #2508, but I can't make this problem happen on demand so testing is inconclusive.