Class: LXC::Extra::Selector
- Inherits:
-
Object
- Object
- LXC::Extra::Selector
- Defined in:
- lib/lxc/extra/selector.rb
Overview
Provides a way to listen to multiple disparate file descriptors with different callbacks to handle each one.
Example
require 'lxc/extra/selector'
require 'socket'
def repeat_to(socket, selector, out)
, *other = socket.recvmsg
if .size == 0
selector.delete(socket)
return
end
out.write()
end
selector = LXC::Extra::Selector.new()
# Listen on 20480 and echo output to STDOUT
server = TCPServer.new(20480)
selector.on_select(server) do |server|
socket = server.accept
selector.on_select(socket, selector, STDOUT, &method(:repeat_to))
end
# Listen on 20481 and echo output to STDERR
server = TCPServer.new(2049)
selector.on_select(server) do |server|
socket = server.accept
selector.on_select(socket, selector, STDERR, &method(:repeat_to))
end
# Do all that listening on one thread!
selector.main_loop
NOTE: This is not presently thread-safe in that adds and deletes must be done on the same thread as the main_loop.
Instance Method Summary collapse
-
#delete(fd) ⇒ Object
Stop listening to a file descriptor.
-
#initialize ⇒ Selector
constructor
Create a new selector.
-
#main_loop ⇒ Object
Listen for any of the given file handles to be ready (with IO.select) and call their callbacks when they are.
-
#on_select(fd, *args, &callback) ⇒ Object
Add a file descriptor to listen on.
Constructor Details
#initialize ⇒ Selector
Create a new selector.
47 48 49 |
# File 'lib/lxc/extra/selector.rb', line 47 def initialize @fd_callbacks = {} end |
Instance Method Details
#delete(fd) ⇒ Object
Stop listening to a file descriptor.
Arguments
- fd
-
file descriptor to stop listening to.
74 75 76 |
# File 'lib/lxc/extra/selector.rb', line 74 def delete(fd) @fd_callbacks.delete(fd) end |
#main_loop ⇒ Object
Listen for any of the given file handles to be ready (with IO.select) and call their callbacks when they are.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/lxc/extra/selector.rb', line 82 def main_loop begin while true ready = IO.select(@fd_callbacks.keys) ready[0].each do |fd| callback = @fd_callbacks[fd] if callback args = [ fd ] args += callback[:args] if callback[:args] if callback[:callback].call(*args) == :stop return end end end end rescue raise end end |
#on_select(fd, *args, &callback) ⇒ Object
Add a file descriptor to listen on.
Arguments
- fd
-
file descriptor to listen on.
- args
-
optional set of arguments to pass to callback
- callback
-
callback to call when file descriptor has data available
60 61 62 63 64 65 |
# File 'lib/lxc/extra/selector.rb', line 60 def on_select(fd, *args, &callback) @fd_callbacks[fd] = { :args => args, :callback => callback } end |