From 133db615e700167dac0e9764f7bf628534d13f8f Mon Sep 17 00:00:00 2001 From: tan Date: Thu, 5 Sep 2024 05:24:26 +0530 Subject: [PATCH] fix cancelling upload requests Cancelling an upload (PUT) request using the mechanism introduced in #256 was not effective. The upload task was not interrupted, which still blocked and the call to `request` did not return. With this change, cancelling also closes the `input` stream of the request to unblock the upload task. Also changed the `interrupted` variable to be an `Atomic{Bool}`. Ref discussion [here](https://github.com/JuliaLang/Downloads.jl/pull/256#discussion_r1742148570). --- src/Downloads.jl | 7 ++++--- test/runtests.jl | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Downloads.jl b/src/Downloads.jl index 7ad35ab..4d3fbcf 100644 --- a/src/Downloads.jl +++ b/src/Downloads.jl @@ -396,7 +396,7 @@ function request( # do the request add_handle(downloader.multi, easy) - interrupted = false + interrupted = Threads.Atomic{Bool}(false) if interrupt !== nothing interrupt_task = @async begin # wait for the interrupt event @@ -405,7 +405,8 @@ function request( remove_handle(downloader.multi, easy) close(easy.output) close(easy.progress) - interrupted = true + interrupted[] = true + close(input) end else interrupt_task = nothing @@ -425,7 +426,7 @@ function request( end end finally - if !interrupted + if !(interrupted[]) if interrupt_task !== nothing # trigger interrupt notify(interrupt) diff --git a/test/runtests.jl b/test/runtests.jl index f4b3ffb..51bffc8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -478,6 +478,16 @@ include("setup.jl") timedwait(()->istaskdone(download_task), 5.0) @test istaskdone(download_task) @test download_task.result isa RequestError + + url = "$server/put" + input=`sh -c 'sleep 15; echo "hello"'` + download_task = @async request(url; interrupt=interrupt, input=input) + sleep(0.1) + @test !istaskdone(download_task) + notify(interrupt) + timedwait(()->istaskdone(download_task), 5.0) + @test istaskdone(download_task) + @test download_task.result isa RequestError end @testset "progress" begin