Skip to content

Commit

Permalink
Capture where the cancellation request came from.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Aug 15, 2019
1 parent 46c975f commit a53cf29
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lib/async/wrapper.rb
Expand Up @@ -24,9 +24,29 @@ module Async
# Represents an asynchronous IO within a reactor.
class Wrapper
class Cancelled < StandardError
class From
def initialize
@backtrace = caller[5..-1]
end

attr :backtrace

def cause
nil
end

def message
"Cancelled"
end
end

def initialize
super "The operation has been cancelled!"

This comment has been minimized.

Copy link
@ioquatix

ioquatix Aug 16, 2019

Author Member

@nobu it would be better to write super "...", cause: From.new

This comment has been minimized.

Copy link
@eregon

eregon Aug 17, 2019

What does the output look like? It seems From is just repeating the backtrace from Cancelled, why is it needed?

This comment has been minimized.

Copy link
@ioquatix

ioquatix Aug 17, 2019

Author Member

It captures the backtrace of who cancelled the IO, which is then shipped across the fiber boundary and raised it's own exception. If you don't have it, all you know is where the IO was when it was cancelled, but not WHY it was cancelled (i.e. the caller backtrace).

This comment has been minimized.

Copy link
@ioquatix

ioquatix Aug 17, 2019

Author Member

I'm actually happy with this solution as it works fine, but it seems a bit inconsistent that there is no way to fully construct StandardError with a specified cause:.

This comment has been minimized.

Copy link
@ioquatix

ioquatix Aug 17, 2019

Author Member

Let me know if that's not clear enough and I'll make a short test case you can try out. I should probably write a spec for it anyway.

This comment has been minimized.

Copy link
@eregon

eregon Aug 17, 2019

Yeah that makes sense, I guess it's not that usual to pass exceptions across fibers explicitly.

I agree super(cause:) would be better, because the implementation might read an internal field instead of dynamically calling cause (whether that happens on MRI would be good to spec)


@cause = From.new
end

attr :cause
end

# wait_readable, wait_writable and wait_any are not re-entrant, and will raise this failure.
Expand Down

0 comments on commit a53cf29

Please sign in to comment.