Class: Cmds::IOHandler
- Inherits:
-
Object
- Object
- Cmds::IOHandler
- Defined in:
- lib/cmds/io_handler.rb
Overview
Class for handling IO from threads and passing it back via a Queue to the main thread for processing.
NOTE These are one-use only! Don't try to reuse them.
Instance Attribute Summary collapse
-
#err ⇒ Object
Returns the value of attribute err.
-
#in ⇒ Object
Returns the value of attribute in.
-
#out ⇒ Object
Returns the value of attribute out.
Instance Method Summary collapse
-
#initialize ⇒ IOHandler
constructor
A new instance of IOHandler.
- #on_err(&block) ⇒ Object
- #on_out(&block) ⇒ Object
- #start ⇒ Object
-
#thread_send_err(line) ⇒ Object
called in separate thread handling process IO.
-
#thread_send_line(sym, line) ⇒ Object
called in separate thread handling process IO.
-
#thread_send_out(line) ⇒ Object
called in separate thread handling process IO.
Constructor Details
#initialize ⇒ IOHandler
Returns a new instance of IOHandler.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cmds/io_handler.rb', line 10 def initialize @in = nil @out = $stdout @err = $stderr # Initialize a thread-safe queue for passing output from the IO threads # back to the main thread # # NOTE This used to be done in {#start}, but I was seeing intermittent # failures on Travis from what look like thread race conditions, # guessing that it's from output arriving before {#start} is # called, which totally looks like it could happen. # # See the failure in # # https://travis-ci.org/nrser/qb/jobs/348609316 # # Really, I'm surprised I haven't hit more issues with this # half-ass threading shit. # # Anyways, I moved the queue creation here, see if it helps. # @queue = Queue.new # Flag that is set to `true` when {#start} is called. @started = false end |
Instance Attribute Details
#err ⇒ Object
Returns the value of attribute err.
8 9 10 |
# File 'lib/cmds/io_handler.rb', line 8 def err @err end |
#in ⇒ Object
Returns the value of attribute in.
8 9 10 |
# File 'lib/cmds/io_handler.rb', line 8 def in @in end |
#out ⇒ Object
Returns the value of attribute out.
8 9 10 |
# File 'lib/cmds/io_handler.rb', line 8 def out @out end |
Instance Method Details
#on_err(&block) ⇒ Object
57 58 59 |
# File 'lib/cmds/io_handler.rb', line 57 def on_err &block @err = block end |
#on_out(&block) ⇒ Object
48 49 50 |
# File 'lib/cmds/io_handler.rb', line 48 def on_out &block @out = block end |
#start ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/cmds/io_handler.rb', line 71 def start if @started raise "This handler has already been started / run" end @started = true # if out is a proc, it's not done out_done = ! @out.is_a?(Proc) # same for err err_done = ! @err.is_a?(Proc) until out_done && err_done key, line = @queue.pop case key when :out if line.nil? out_done = true else handle_line @out, line end when :err if line.nil? err_done = true else handle_line @err, line end else raise "bad key: #{ key.inspect }" end end end |
#thread_send_err(line) ⇒ Object
called in separate thread handling process IO
62 63 64 |
# File 'lib/cmds/io_handler.rb', line 62 def thread_send_err line @queue << [:err, line] end |
#thread_send_line(sym, line) ⇒ Object
called in separate thread handling process IO
67 68 69 |
# File 'lib/cmds/io_handler.rb', line 67 def thread_send_line sym, line @queue << [sym, line] end |
#thread_send_out(line) ⇒ Object
called in separate thread handling process IO
53 54 55 |
# File 'lib/cmds/io_handler.rb', line 53 def thread_send_out line @queue << [:out, line] end |