Module: RightScale::Windows::PipeServerHandler
- Defined in:
- lib/chef/windows/pipe_server.rb
Overview
Provides an eventmachine callback handler for the server pipe.
Constant Summary collapse
- CONNECTING_STATE =
state between client connections
0- READING_STATE =
after connection, receiving request
1- RESPONDING_STATE =
received request, calculating response
2- WRITING_STATE =
calculated response, respond before disconnecting
3- WAIT_SLEEP_DELAY_MSECS =
yield to avoid busy looping
0.001
- ASYNC_IO_SLEEP_DELAY_MSECS =
yield to allow async I/O time to process
0.01
Instance Method Summary collapse
-
#force_detach ⇒ Object
Forces detachment of the handler unless already unbound.
-
#initialize(options) ⇒ Object
Parameters options(Hash):: A hash containing the following options by token name:.
-
#notify_readable ⇒ Object
Callback from EM to asynchronously read the pipe stream.
-
#receive_data(data) ⇒ Object
Callback from EM to receive data, which we also use to handle the asynchronous data we read ourselves.
-
#unbind ⇒ Object
Callback from EM to unbind.
Instance Method Details
#force_detach ⇒ Object
Forces detachment of the handler unless already unbound.
102 103 104 105 106 107 |
# File 'lib/chef/windows/pipe_server.rb', line 102 def force_detach # No need to use next tick to prevent issue in EM where # descriptors list gets out-of-sync when calling detach # in an unbind callback detach unless @unbound end |
#initialize(options) ⇒ Object
Parameters
- options(Hash)
-
A hash containing the following options by token name:
- target(Object)
-
Object defining handler methods to be called (required).
- request_handler(Token)
-
Token for request handler method name (required).
- request_query(Token)
-
Token for request query method name if server
needs time to calculate a response (allows event loop to continue until such time as request_query returns true).
- pipe(IO)
-
pipe object (required).
54 55 56 57 58 59 60 61 62 |
# File 'lib/chef/windows/pipe_server.rb', line 54 def initialize() raise "Missing required :target" unless @target = [:target] raise "Missing required :request_handler" unless @request_handler = [:request_handler] raise "Missing require :pipe" unless @pipe = [:pipe] @request_query = [:request_query] @unbound = false @state = CONNECTING_STATE @data = nil end |
#notify_readable ⇒ Object
Callback from EM to asynchronously read the pipe stream. Note that this callback mechanism is deprecated after EM v0.12.8
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/chef/windows/pipe_server.rb', line 66 def notify_readable if @state == RESPONDING_STATE || @pipe.wait(WAIT_SLEEP_DELAY_MSECS) if @pipe.pending? handle_pending else handle_non_pending end # sleep a little to allow asynchronous I/O time to complete and # avoid busy looping. sleep ASYNC_IO_SLEEP_DELAY_MSECS end rescue Exception => e RightScale::Log.error("Failed to send data to Powershell", e, :trace) (disconnect rescue nil) if @state != CONNECTING_STATE end |
#receive_data(data) ⇒ Object
Callback from EM to receive data, which we also use to handle the asynchronous data we read ourselves.
85 86 87 88 89 90 |
# File 'lib/chef/windows/pipe_server.rb', line 85 def receive_data(data) # automagically append a newlineto make it easier to parse response. result = @target.method(@request_handler).call(data) result += "\n" unless result[-1] == "\n"[0] return result end |
#unbind ⇒ Object
Callback from EM to unbind.
93 94 95 96 97 98 99 |
# File 'lib/chef/windows/pipe_server.rb', line 93 def unbind Log.debug("unbound") @pipe.close rescue nil @connected = false @pipe = nil @unbound = true end |