Skip to content

Commit

Permalink
fix cancelling upload requests (#259)
Browse files Browse the repository at this point in the history
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](#256 (comment)).
  • Loading branch information
tanmaykm authored Sep 9, 2024
1 parent df33406 commit 89d3c7d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/Curl/Easy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,11 @@ function upload_data(easy::Easy, input::IO)
curl_easy_pause(easy.handle, Curl.CURLPAUSE_CONT)
wait(easy.ready)
easy.input === nothing && break
easy.ready = Threads.Event()
if hasmethod(reset, (Base.Event,))
reset(easy.ready)
else
easy.ready = Threads.Event()
end
end
end

Expand Down
8 changes: 5 additions & 3 deletions src/Downloads.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -405,7 +405,9 @@ function request(
remove_handle(downloader.multi, easy)
close(easy.output)
close(easy.progress)
interrupted = true
interrupted[] = true
close(input)
notify(easy.ready)
end
else
interrupt_task = nothing
Expand All @@ -425,7 +427,7 @@ function request(
end
end
finally
if !interrupted
if !(interrupted[])
if interrupt_task !== nothing
# trigger interrupt
notify(interrupt)
Expand Down
11 changes: 11 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,17 @@ include("setup.jl")
timedwait(()->istaskdone(download_task), 5.0)
@test istaskdone(download_task)
@test download_task.result isa RequestError

interrupt = Base.Event()
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
Expand Down

0 comments on commit 89d3c7d

Please sign in to comment.