Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita5ab4f5

Browse files
authored
feat: allow cancelation of download of a different URL (#71)
Respects the cancelation token provided to `StartDownloadAsync` even when there is another download already in progress to the same destination.
1 parent272895b commita5ab4f5

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

‎Tests.Vpn.Service/DownloaderTest.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,32 @@ public async Task MismatchedETag(CancellationToken ct)
412412
Assert.That(ex.Message,Does.Contain("ETag does not match SHA1 hash of downloaded file").And.Contains("beef"));
413413
}
414414

415+
[Test(Description="Timeout waiting for existing download")]
416+
[CancelAfter(30_000)]
417+
publicasyncTaskCancelledWaitingForOther(CancellationTokenct)
418+
{
419+
vartestCts=CancellationTokenSource.CreateLinkedTokenSource(ct);
420+
usingvarhttpServer=newTestHttpServer(async _=>
421+
{
422+
awaitTask.Delay(TimeSpan.FromSeconds(5),testCts.Token);
423+
});
424+
varurl0=newUri(httpServer.BaseUrl+"/test0");
425+
varurl1=newUri(httpServer.BaseUrl+"/test1");
426+
vardestPath=Path.Combine(_tempDir,"test");
427+
varmanager=newDownloader(NullLogger<Downloader>.Instance);
428+
429+
// first outer task succeeds, getting download started
430+
vardlTask0=awaitmanager.StartDownloadAsync(newHttpRequestMessage(HttpMethod.Get,url0),destPath,
431+
NullDownloadValidator.Instance,testCts.Token);
432+
433+
// The second request fails if the timeout is short
434+
varsmallerCt=newCancellationTokenSource(TimeSpan.FromSeconds(1)).Token;
435+
Assert.ThrowsAsync<TaskCanceledException>(async()=>awaitmanager.StartDownloadAsync(
436+
newHttpRequestMessage(HttpMethod.Get,url1),destPath,
437+
NullDownloadValidator.Instance,smallerCt));
438+
awaittestCts.CancelAsync();
439+
}
440+
415441
[Test(Description="Timeout on response body")]
416442
[CancelAfter(30_000)]
417443
publicasyncTaskCancelledInner(CancellationTokenct)

‎Vpn.Service/Downloader.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ public async Task<DownloadTask> StartDownloadAsync(HttpRequestMessage req, strin
287287
{
288288
while(true)
289289
{
290+
ct.ThrowIfCancellationRequested();
290291
vartask=_downloads.GetOrAdd(destinationPath,
291292
_=>newDownloadTask(_logger,req,destinationPath,validator));
292293
// EnsureStarted is a no-op if we didn't create a new DownloadTask.
@@ -322,7 +323,22 @@ public async Task<DownloadTask> StartDownloadAsync(HttpRequestMessage req, strin
322323
_logger.LogWarning(
323324
"Download for '{DestinationPath}' is already in progress, but is for a different Url - awaiting completion",
324325
destinationPath);
325-
awaittask.Task;
326+
awaitTaskOrCancellation(task.Task,ct);
327+
}
328+
}
329+
330+
/// <summary>
331+
/// TaskOrCancellation waits for either the task to complete, or the given token to be canceled.
332+
/// </summary>
333+
internalstaticasyncTaskTaskOrCancellation(Tasktask,CancellationTokencancellationToken)
334+
{
335+
varcancellationTask=newTaskCompletionSource();
336+
awaitusing(cancellationToken.Register(()=>cancellationTask.TrySetCanceled()))
337+
{
338+
// Wait for either the task or the cancellation
339+
varcompletedTask=awaitTask.WhenAny(task,cancellationTask.Task);
340+
// Await to propagate exceptions, if any
341+
awaitcompletedTask;
326342
}
327343
}
328344
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp