Class: Pione::Command::Spawner
- Inherits:
-
Object
- Object
- Pione::Command::Spawner
- Defined in:
- lib/pione/command/spawner.rb
Overview
Spawner is a utility class for calling pione commands as different process. We assume both caller and callee commands have front server.
Instance Attribute Summary collapse
-
#child_front ⇒ Object
readonly
front URI of spawned child process.
-
#pid ⇒ Object
readonly
PID of spawned child process.
-
#thread ⇒ Object
readonly
watch thread for spawned child process.
Instance Method Summary collapse
-
#initialize(model, name) ⇒ Spawner
constructor
A new instance of Spawner.
-
#option(*argv) ⇒ Object
Add arguments as command arguments.
-
#option_from(table, key, option_name, converter = nil) ⇒ void
Add the option name and the value as command arguments.
-
#option_if(cond, *args) ⇒ Object
Add arguments if the condition is true.
-
#spawn ⇒ Object
Spawn the command process.
-
#when_terminated(&b) ⇒ Object
Register the block that is executed when the spawned process is terminated.
Constructor Details
#initialize(model, name) ⇒ Spawner
Returns a new instance of Spawner.
10 11 12 13 14 |
# File 'lib/pione/command/spawner.rb', line 10 def initialize(model, name) @model = model # caller's model @name = name # callee command name @argv = [] # callee command arguments end |
Instance Attribute Details
#child_front ⇒ Object (readonly)
front URI of spawned child process
7 8 9 |
# File 'lib/pione/command/spawner.rb', line 7 def child_front @child_front end |
#pid ⇒ Object (readonly)
PID of spawned child process
6 7 8 |
# File 'lib/pione/command/spawner.rb', line 6 def pid @pid end |
#thread ⇒ Object (readonly)
watch thread for spawned child process
8 9 10 |
# File 'lib/pione/command/spawner.rb', line 8 def thread @thread end |
Instance Method Details
#option(*argv) ⇒ Object
Add arguments as command arguments.
62 63 64 |
# File 'lib/pione/command/spawner.rb', line 62 def option(*argv) @argv += argv.map {|val| val.to_s} end |
#option_from(table, key, option_name, converter = nil) ⇒ void
This method returns an undefined value.
Add the option name and the value as command arguments. If the value
doesn't exist in the table or the value is nil
, no options are
added. This is useful for the case a caller's command option passes
callee's.
85 86 87 88 89 90 91 |
# File 'lib/pione/command/spawner.rb', line 85 def option_from(table, key, option_name, converter=nil) if table[key] val = table[key] val = converter.call(val) if converter option(option_name, val) end end |
#option_if(cond, *args) ⇒ Object
Add arguments if the condition is true.
67 68 69 70 71 |
# File 'lib/pione/command/spawner.rb', line 67 def option_if(cond, *args) if cond option(*args) end end |
#spawn ⇒ Object
Spawn the command process.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pione/command/spawner.rb', line 17 def spawn Log::Debug.system('process "%{name}" is spawned with arguments %{argv}' % {name: @name, argv: @argv}) # create a new process and watch it @pid = Process.spawn(@name, *@argv) # keep to watch child process @thread = Process.detach(@pid) # fail to spawn if the monitor thread is nil unless @thread return self end # find child front while child process is alive Timeout.timeout(10) do while @thread.alive? do # find front and save its uri and pid if child_front = find_child_front(@pid) @child_front = child_front return self else sleep 0.1 end end # error if the process has failed unless not(@thread.alive?) and @thread.value.success? raise SpawnError.child_process_is_dead(@model[:scenario_name], @name, @argv) end return self end rescue Timeout::Error raise SpawnError.new(@model[:scenario_name], @name, @argv, "timed out") rescue Object => e if e.kind_of?(SpawnError) raise else raise SpawnError.new(@model[:scenario_name], @name, @argv, e.) end end |
#when_terminated(&b) ⇒ Object
Register the block that is executed when the spawned process is terminated.
94 95 96 97 98 99 |
# File 'lib/pione/command/spawner.rb', line 94 def when_terminated(&b) Thread.new do @thread.join b.call end end |