lib/cmds/io_handler.rb in cmds-0.2.9 vs lib/cmds/io_handler.rb in cmds-0.2.10
- old
+ new
@@ -1,13 +1,40 @@
class Cmds
+ # 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.
+ #
class IOHandler
attr_accessor :in, :out, :err
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
def out= value
value = value.to_s if value.is_a? Pathname
@out = value
@@ -20,31 +47,34 @@
def on_out &block
@out = block
end
- # called in seperate thread handling process IO
+ # called in separate thread handling process IO
def thread_send_out line
@queue << [:out, line]
end
def on_err &block
@err = block
end
- # called in seperate thread handling process IO
+ # called in separate thread handling process IO
def thread_send_err line
@queue << [:err, line]
end
-
+
+ # called in separate thread handling process IO
def thread_send_line sym, line
@queue << [sym, line]
end
def start
- # Initialize a thread-safe queue for passing output from the IO threads
- # back to the main thread
- @queue = Queue.new
+ 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)