Class: Async::Wrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/async/wrapper.rb

Overview

Represents an asynchronous IO within a reactor.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, reactor = nil) ⇒ Wrapper

Returns a new instance of Wrapper.

Parameters:

  • io

    the native object to wrap.

  • reactor (Reactor) (defaults to: nil)

    the reactor that is managing this wrapper, or not specified, it’s looked up by way of Task.current.

  • bound (Boolean)

    whether the underlying socket will be closed if the wrapper is closed.



29
30
31
32
33
34
# File 'lib/async/wrapper.rb', line 29

def initialize(io, reactor = nil)
	@io = io
	
	@reactor = reactor
	@monitor = nil
end

Instance Attribute Details

#ioObject (readonly)

The underlying native io.



37
38
39
# File 'lib/async/wrapper.rb', line 37

def io
  @io
end

#reactorObject

The reactor this wrapper is associated with, if any.



40
41
42
# File 'lib/async/wrapper.rb', line 40

def reactor
  @reactor
end

Instance Method Details

#closeObject

Close the io and monitor.



93
94
95
96
97
# File 'lib/async/wrapper.rb', line 93

def close
	@monitor.close if @monitor
	
	@io.close
end

#wait_any(interests = :rw, duration = nil) ⇒ Object

Wait fo the io to become either readable or writable.

Parameters:

  • interests (:r | :w | :rw) (defaults to: :rw)

    what events to wait for.

  • duration (Float) (defaults to: nil)

    timeout after the given duration if not nil.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/async/wrapper.rb', line 64

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.remove_interest(@monitor.interests)
			@monitor.value = nil
		end
	else
		reactor = Task.current.reactor
		monitor = reactor.register(@io, interests)
		
		begin
			wait_for(reactor, monitor, duration)
		ensure
			monitor.close
		end
	end
end

#wait_readable(duration = nil) ⇒ Object

Wait for the io to become readable.



52
53
54
# File 'lib/async/wrapper.rb', line 52

def wait_readable(duration = nil)
	wait_any(:r, duration)
end

#wait_writable(duration = nil) ⇒ Object

Wait for the io to become writable.



57
58
59
# File 'lib/async/wrapper.rb', line 57

def wait_writable(duration = nil)
	wait_any(:w, duration)
end