class Async::Wrapper
Represents an asynchronous IO within a reactor.
def close
def close if @monitor @monitor.close @monitor = nil end @io.close end
def initialize(io, reactor = nil)
-
bound
(Boolean
) -- whether the underlying socket will be closed if the wrapper is closed. -
reactor
(Reactor
) -- the reactor that is managing this wrapper, or not specified, it's looked up by way of {Task.current}. -
io
() -- the native object to wrap.
def initialize(io, reactor = nil) @io = io @reactor = reactor @monitor = nil end
def reactor= reactor
Bind this wrapper to a different reactor. Assign nil to convert to an unbound wrapper (can be used from any reactor/task but with slightly increased overhead.)
def reactor= reactor if @monitor @monitor.close @monitor = nil end @reactor = reactor end
def wait_any(interests = :rw, duration = nil)
-
duration
(Float
) -- timeout after the given duration if not `nil`. -
interests
(:r | :w | :rw
) -- what events to wait for.
def wait_any(interests = :rw, duration = nil) # There is value in caching this monitor - if you can reuse it, you will get about 2x the throughput, because you avoid calling Reactor#register and Monitor#close for every call. That being said, by caching it, you also introduce lifetime issues. I'm going to accept this overhead into the wrapper design because it's pretty convenient, but if you want faster IO, take a look at the performance spec which compares this method with a more direct alternative. if @reactor unless @monitor @monitor = @reactor.register(@io, interests) else @monitor.interests = interests @monitor.value = Fiber.current end begin wait_for(@reactor, @monitor, duration) ensure @monitor.interests = nil end else reactor = Task.current.reactor monitor = reactor.register(@io, interests) begin wait_for(reactor, monitor, duration) ensure monitor.close end end end
def wait_for(reactor, monitor, duration)
def wait_for(reactor, monitor, duration) # If the user requested an explicit timeout for this operation: if duration reactor.timeout(duration) do Task.yield end else Task.yield end return true end
def wait_readable(duration = nil)
def wait_readable(duration = nil) wait_any(:r, duration) end
def wait_writable(duration = nil)
def wait_writable(duration = nil) wait_any(:w, duration) end