Class: Cmds::IOHandler

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initializeIOHandler

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

#errObject

Returns the value of attribute err.



8
9
10
# File 'lib/cmds/io_handler.rb', line 8

def err
  @err
end

#inObject

Returns the value of attribute in.



8
9
10
# File 'lib/cmds/io_handler.rb', line 8

def in
  @in
end

#outObject

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

#startObject



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