Class: Pione::RuleEngine::ActionHandler
- Inherits:
-
BasicHandler
- Object
- BasicHandler
- Pione::RuleEngine::ActionHandler
- Defined in:
- lib/pione/rule-engine/action-handler.rb
Overview
ActionHandler handles ActionRule.
Constant Summary
Constants included from Log::MessageLog
Log::MessageLog::MESSAGE_QUEUE
Instance Attribute Summary collapse
-
#working_directory ⇒ Object
readonly
Returns the value of attribute working_directory.
Attributes inherited from BasicHandler
#base_location, #caller_id, #digest, #domain_id, #domain_location, #dry_run, #env, #inputs, #outputs, #package_id, #param_set, #plain_env, #rule_condition, #rule_definition, #rule_name
Class Method Summary collapse
Instance Method Summary collapse
-
#call_shell_script(path) ⇒ Object
Call shell script of the path.
-
#collect_outputs ⇒ void
Collect output data by names from working directory.
-
#execute ⇒ Object
Execute the action.
-
#initialize(*args) ⇒ ActionHandler
constructor
A new instance of ActionHandler.
-
#make_output_tuple_with_time(name) ⇒ Object
Make output tuple by name.
-
#setup_variable_table ⇒ Object
Setup the variable table with working directory in addition.
-
#setup_working_directory ⇒ Object
Synchronize input data into working directory.
-
#write_env_info ⇒ Object
Write action environment information file.
-
#write_other_resources ⇒ Object
Move other intermediate files to the domain location.
-
#write_output_data(outputs) ⇒ void
Write output data with caching.
-
#write_output_tuples(outputs) ⇒ Object
Writes output tuples into the tuple space server.
-
#write_shell_script(&b) ⇒ Object
Write the action into a shell script.
Methods inherited from BasicHandler
#apply_touch_operation, #create_data_by_touch_operation, #find_outputs_from_space, #handle, #make_location, #make_output_location, #make_output_tuple, #make_rule_process_record, #make_task_process_record, #publish_outputs, #setup_env, #show_outputs, #update_time_by_touch_operation, #write_data_null
Methods included from Log::MessageLog
#debug_message, #debug_message_begin, #debug_message_end, debug_mode, debug_mode=, debug_mode?, message, quiet_mode, quiet_mode=, quiet_mode?, #show, #user_message, #user_message_begin, #user_message_end
Methods included from TupleSpace::TupleSpaceInterface
#process_log, #processing_error, #read!, #set_tuple_space, #take!, #take_all!, tuple_space_operation, #tuple_space_server, #with_process_log
Constructor Details
#initialize(*args) ⇒ ActionHandler
Returns a new instance of ActionHandler.
11 12 13 14 15 16 17 18 |
# File 'lib/pione/rule-engine/action-handler.rb', line 11 def initialize(*args) super(*args) @working_directory = Location[Global.working_directory_generator.mkdir] @env.variable_set( Lang::Variable.new("__WORKING_DIRECTORY__"), Lang::StringSequence.of(@working_directory.path.to_s) ) end |
Instance Attribute Details
#working_directory ⇒ Object (readonly)
Returns the value of attribute working_directory.
9 10 11 |
# File 'lib/pione/rule-engine/action-handler.rb', line 9 def working_directory @working_directory end |
Class Method Details
.message_name ⇒ Object
5 6 7 |
# File 'lib/pione/rule-engine/action-handler.rb', line 5 def self. "Action" end |
Instance Method Details
#call_shell_script(path) ⇒ Object
Call shell script of the path.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/pione/rule-engine/action-handler.rb', line 105 def call_shell_script(path) scriptname = File.basename(path) # stdout & stderr rule_condition = @rule_definition.rule_condition_context.eval(@env) output_conditions = rule_condition.outputs.map {|output| output.eval(@env)} stdout = output_conditions.find{|output| output.output_mode == :stdout} out = stdout ? stdout.pieces.first.pattern : ".stdout" err = ".stderr" # execute command `cd #{@working_directory.path}; PATH=#{(@working_directory + "bin").path}:$PATH ; ./#{scriptname} > #{out} 2> #{err}` # the case the script has errored unless $?.success? raise ActionError.new(digest, (@working_directory + err).read) end # delete .stdout file if it is empty if stdout.nil? and (@working_directory + out).size == 0 (@working_directory + out).delete end # delete .stderr file if it is emtpy if (@working_directory + err).size == 0 (@working_directory + err).delete end end |
#collect_outputs ⇒ void
This method returns an undefined value.
Collect output data by names from working directory.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/pione/rule-engine/action-handler.rb', line 144 def collect_outputs outputs = [] filenames = @working_directory.file_entries.map{|entry| entry.path.basename.to_s} @rule_condition.outputs.each_with_index do |condition, i| _condition = condition.eval(@env) case _condition.distribution when :all outputs[i] = filenames.select{|name| _condition.match?(name)}.map do |name| make_output_tuple_with_time(name) end when :each if name = filenames.find {|name| _condition.match?(name)} outputs[i] = [make_output_tuple_with_time(name)] end end # apply touch operation if tuple = apply_touch_operation(_condition, outputs[i]) outputs[i] = tuple end # write data null if needed write_data_null(_condition, outputs[i], i) end return outputs end |
#execute ⇒ Object
Execute the action.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/pione/rule-engine/action-handler.rb', line 21 def execute # prepare input files setup_working_directory # prepare shell script write_shell_script {|path| call_shell_script(path) } # collect outputs outputs = collect_outputs # write output data write_output_data(outputs) # write tuples write_output_tuples(outputs) # write environment info write_env_info # write other resources write_other_resources # clear working directory @working_directory.delete # return tuples return outputs end |
#make_output_tuple_with_time(name) ⇒ Object
Make output tuple by name.
135 136 137 138 139 |
# File 'lib/pione/rule-engine/action-handler.rb', line 135 def make_output_tuple_with_time(name) time = (@working_directory + name).mtime location = make_output_location(name) TupleSpace::DataTuple.new(name: name, domain: @domain_id, location: location, time: time) end |
#setup_variable_table ⇒ Object
Setup the variable table with working directory in addition.
45 46 47 48 49 50 |
# File 'lib/pione/rule-engine/action-handler.rb', line 45 def setup_variable_table super @variable_table.set(Variable.new("__BASE__"), PioneString.new(base_location.uri).to_seq) @variable_table.set(Variable.new("_"), PackageExprSequence.new([PackageExpr.new(@rule.package_name)])) end |
#setup_working_directory ⇒ Object
Synchronize input data into working directory.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/pione/rule-engine/action-handler.rb', line 53 def setup_working_directory @inputs.flatten.each do |input| # get file path in working directory wd_location = @working_directory + input.name # create a link to cache cache_location = System::FileCache.get(input.location) wd_location.path.make_symlink(cache_location.path) unless wd_location.exist? raise RuleExecutionError.new(self) end end # FIXME: should not copy bin files in the package each time. bin = @base_location + "package" + "bin" if bin.exist? bin.entries.each do |entry| dest = @working_directory + "bin" + entry.basename unless dest.exist? entry.copy(dest) dest.path.chmod(0700) end end end end |
#write_env_info ⇒ Object
Write action environment information file.
184 185 186 187 188 189 |
# File 'lib/pione/rule-engine/action-handler.rb', line 184 def write_env_info @env.variable_table.keys.map do |var| val = @env.variable_get(var) "%s: %s" % [var.name, val.textize] end.tap {|x| (@working_directory + ".pione-env").create(x.join("\n"))} end |
#write_other_resources ⇒ Object
Move other intermediate files to the domain location.
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/pione/rule-engine/action-handler.rb', line 192 def write_other_resources @working_directory.file_entries.each do |entry| location = make_location(entry.path.basename, @domain_id) begin entry.move(location) rescue => e Log::SystemLog.warn("cannot move %s to %s: %s" % [entry.path, location, e.]) end end end |
#write_output_data(outputs) ⇒ void
This method returns an undefined value.
Write output data with caching.
175 176 177 178 179 180 181 |
# File 'lib/pione/rule-engine/action-handler.rb', line 175 def write_output_data(outputs) outputs.flatten.compact.each do |output| src = @working_directory + output.name dest = output.location System::FileCache.put(src, dest) end end |
#write_output_tuples(outputs) ⇒ Object
Writes output tuples into the tuple space server.
204 205 206 |
# File 'lib/pione/rule-engine/action-handler.rb', line 204 def write_output_tuples(outputs) outputs.flatten.compact.each {|output| write(output)} end |
#write_shell_script(&b) ⇒ Object
Write the action into a shell script.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/pione/rule-engine/action-handler.rb', line 79 def write_shell_script(&b) file = @working_directory + "__pione-action__.sh" # write the action if @dry_run @rule.outputs.flatten.each do |output| file.create("touch %s" % output.eval(@env).name) end else # apply offside rule content = @rule_definition.action_context.eval(@env).content file.create(Util::EmbededExprExpander.(@env, content)) # chmod 700 if @working_directory.scheme == "local" FileUtils.chmod(0700, file.path) end end # message lines = @rule_definition.action_context.eval(@env).content.split("\n") (["-"*60, lines, "-"*60].flatten, 0, "SH") return b.call(file.path) end |