Class: Pione::RuleEngine::BasicHandler
- Inherits:
-
Object
- Object
- Pione::RuleEngine::BasicHandler
- Includes:
- Log::MessageLog, TupleSpace::TupleSpaceInterface
- Defined in:
- lib/pione/rule-engine/basic-handler.rb
Overview
BasicHandler is a base class for rule handlers.
Direct Known Subclasses
Constant Summary
Constants included from Log::MessageLog
Log::MessageLog::MESSAGE_QUEUE
Instance Attribute Summary collapse
-
#base_location ⇒ Object
readonly
base location.
-
#caller_id ⇒ Object
readonly
from domain.
-
#digest ⇒ Object
readonly
handler's digest string.
-
#domain_id ⇒ Object
readonly
domain id.
-
#domain_location ⇒ Object
readonly
domain location.
-
#dry_run ⇒ Object
readonly
flag of dry run mode.
-
#env ⇒ Object
readonly
handler's environement.
-
#inputs ⇒ Object
readonly
input tuples.
-
#outputs ⇒ Object
readonly
output tuples.
-
#package_id ⇒ Object
readonly
package id.
-
#param_set ⇒ Object
readonly
parameter set.
-
#plain_env ⇒ Object
readonly
plain environment.
-
#rule_condition ⇒ Object
readonly
rule condtions.
-
#rule_definition ⇒ Object
readonly
definition of the handling rule.
-
#rule_name ⇒ Object
readonly
rule name.
Instance Method Summary collapse
-
#apply_touch_operation(condition, tuples) ⇒ Object
Apply touch operation.
- #create_data_by_touch_operation(condition) ⇒ Object
-
#execute ⇒ Object
Executes the rule.
-
#find_outputs_from_space ⇒ void
Find outputs from the domain space.
-
#handle ⇒ Object
Handle the rule and return the outputs.
-
#initialize(param) ⇒ BasicHandler
constructor
Create a new handler for rule.
-
#make_location(name, domain_id) ⇒ BasicLocation
Make location by data name and the domain.
-
#make_output_location(name) ⇒ Object
Make output data location by the name.
-
#make_output_tuple(data_expr) ⇒ Object
Make output tuple by the name.
-
#make_rule_process_record ⇒ Object
Build rule process record.
- #make_task_process_record ⇒ Object
-
#publish_outputs(outputs) ⇒ Object
Publish output data tuples.
-
#setup_env(env, param_set) ⇒ Object
Setup handler's environment.
-
#show_outputs(outputs) ⇒ Object
Show output tuples as message.
- #update_time_by_touch_operation(tuples) ⇒ Object
-
#write_data_null(output, tuples, i) ⇒ Object
Write a data null tuple if the output condition accepts nonexistence.
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, #set_tuple_space, tuple_space_operation, #tuple_space_server, #with_process_log
Constructor Details
#initialize(param) ⇒ BasicHandler
Create a new handler for rule.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 28 def initialize(param) ### set tuple space server set_tuple_space(param[:tuple_space]) ### set informations @plain_env = param[:env] @env = setup_env(param[:env], param[:param_set]) @package_id = param[:package_id] @rule_name = param[:rule_name] @rule_definition = param[:rule_definition] @rule_condition = @rule_definition.rule_condition_context.eval(@env) @inputs = param[:inputs] @outputs = [] @param_set = param[:param_set] @digest = Util::TaskDigest.generate(@package_id, @rule_name, @inputs, @param_set) @base_location = read!(TupleSpace::BaseLocationTuple.any).location @dry_run = begin read!(TupleSpace::DryRunTuple.any).availability rescue false end @domain_id = param[:domain_id] @domain_location = make_location("", @domain_id) @caller_id = param[:caller_id] @request_from = param[:request_from] @session_id = param[:session_id] @client_ui = param[:client_ui] end |
Instance Attribute Details
#base_location ⇒ Object (readonly)
base location
18 19 20 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 18 def base_location @base_location end |
#caller_id ⇒ Object (readonly)
from domain
22 23 24 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 22 def caller_id @caller_id end |
#digest ⇒ Object (readonly)
handler's digest string
17 18 19 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 17 def digest @digest end |
#domain_id ⇒ Object (readonly)
domain id
20 21 22 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 20 def domain_id @domain_id end |
#domain_location ⇒ Object (readonly)
domain location
21 22 23 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 21 def domain_location @domain_location end |
#dry_run ⇒ Object (readonly)
flag of dry run mode
19 20 21 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 19 def dry_run @dry_run end |
#env ⇒ Object (readonly)
handler's environement
9 10 11 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 9 def env @env end |
#inputs ⇒ Object (readonly)
input tuples
14 15 16 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 14 def inputs @inputs end |
#outputs ⇒ Object (readonly)
output tuples
15 16 17 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 15 def outputs @outputs end |
#package_id ⇒ Object (readonly)
package id
10 11 12 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 10 def package_id @package_id end |
#param_set ⇒ Object (readonly)
parameter set
16 17 18 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 16 def param_set @param_set end |
#plain_env ⇒ Object (readonly)
plain environment
8 9 10 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 8 def plain_env @plain_env end |
#rule_condition ⇒ Object (readonly)
rule condtions
13 14 15 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 13 def rule_condition @rule_condition end |
#rule_definition ⇒ Object (readonly)
definition of the handling rule
12 13 14 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 12 def rule_definition @rule_definition end |
#rule_name ⇒ Object (readonly)
rule name
11 12 13 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 11 def rule_name @rule_name end |
Instance Method Details
#apply_touch_operation(condition, tuples) ⇒ Object
Apply touch operation.
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 181 def apply_touch_operation(condition, tuples) _condition = condition.eval(@env) if _condition.operation == :touch if tuples.empty? create_data_by_touch_operation(_condition) else update_time_by_touch_operation(tuples) end end end |
#create_data_by_touch_operation(condition) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 192 def create_data_by_touch_operation(condition) # NOTE: touch operation applies first piece of data sequence now name = condition.pieces.first.pattern location = @domain_location + name # create a empty file location.create("") unless location.exist? # FIXME: write a touch tuple time = Time.now write(TupleSpace::TouchTuple.new(name: name, domain: @domain_id, time: time)) # FIXME: create an output data tuple data_tuple = TupleSpace::DataTuple.new(name: name, domain: @domain_id, location: location, time: time) write(data_tuple) [data_tuple] end |
#execute ⇒ Object
Executes the rule.
93 94 95 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 93 def execute raise NotImplementError end |
#find_outputs_from_space ⇒ void
This method returns an undefined value.
Find outputs from the domain space.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 154 def find_outputs_from_space tuples = read_all(TupleSpace::DataTuple.new(domain: @domain_id)) outputs = [] @rule_condition.outputs.each_with_index do |condition, i| _condition = condition.eval(@env) case _condition.distribution when :all outputs[i] = tuples.find_all {|t| _condition.match(t.name)} when :each # FIXME outputs[i] = tuples.find_all {|t| _condition.match(t.name)} end # apply touch operation and push the result if new_tuples = apply_touch_operation(_condition, outputs[i]) outputs[i] = new_tuples end # write data null if needed write_data_null(_condition, outputs[i], i) end return outputs end |
#handle ⇒ Object
Handle the rule and return the outputs.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 54 def handle # make rule and task process log process_log(make_task_process_record.merge(transition: "start")) process_log(make_rule_process_record.merge(transition: "start")) # show begin messages (@digest, 0, "==>") ("caller: %s" % @caller_id) unless @domain_id == "root" # save domain log Log::DomainLog.new(self).save # save a domain dump file domain_dump_location = @working_directory ? @working_directory :@domain_location System::DomainDump.new(env.dumpable).write(domain_dump_location) end # execute the rule outputs = execute # publish outputs and finished begin outputs.flatten.compact.each {|output| write(output)} write(TupleSpace::FinishedTuple.new(@domain_id, Util::UUID.generate, :succeeded, outputs)) rescue Rinda::RedundantTupleError write(TupleSpace::FinishedTuple.new(@domain_id, Util::UUID.generate, :error, outputs)) end # show end message show_outputs(outputs) (@digest, 0, "<==") # put rule and task process log process_log(make_rule_process_record.merge(transition: "complete")) process_log(make_task_process_record.merge(transition: "complete")) end |
#make_location(name, domain_id) ⇒ BasicLocation
Make location by data name and the domain.
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 105 def make_location(name, domain_id) if domain_id == "root" return @base_location + "./output/%s" % name else # make relative path pakcage_id, rule_name, task_id = domain_id.split(":") path = "./.%s/%s/%s/%s" % [package_id, rule_name, task_id, name] # make location return @base_location + path end end |
#make_output_location(name) ⇒ Object
Make output data location by the name.
119 120 121 122 123 124 125 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 119 def make_output_location(name) # FIXME: maybe we should not lift output here return if @caller_id.nil? # get parent domain or root domain make_location(name, @caller_id) end |
#make_output_tuple(data_expr) ⇒ Object
Make output tuple by the name.
128 129 130 131 132 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 128 def make_output_tuple(data_expr) name = data_expr.first.name location = make_output_location(name) TupleSpace::DataTuple.new(name: name, domain: @domain_id, location: location, time: nil) end |
#make_rule_process_record ⇒ Object
Build rule process record.
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 228 def make_rule_process_record Log::RuleProcessRecord.new.tap do |record| record.name = "&%s:%s" % [@package_id, @rule_name] record.rule_type = @rule_definition.rule_type if @caller caller_package_id, caller_rule_name, caller_task_id = @caller.split(":") record.caller = "&%s:%s" % [caller_package_id, caller_rule_name] end end end |
#make_task_process_record ⇒ Object
239 240 241 242 243 244 245 246 247 248 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 239 def make_task_process_record Log::TaskProcessRecord.new.tap do |record| record.name = @digest record.package_id = @package_id record.rule_name = @rule_name record.rule_type = @rule_definition.rule_type record.inputs = @inputs.flatten.map{|input| input.name}.join(",") record.parameters = @param_set.textize end end |
#publish_outputs(outputs) ⇒ Object
Publish output data tuples.
251 252 253 254 255 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 251 def publish_outputs(outputs) # output data rescue Rinda::RedundantTupleError write("finished") end |
#setup_env(env, param_set) ⇒ Object
Setup handler's environment. We make a new environment that is introduced a new layer in top of the plain package environment, so we can do any operations safety.
137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 137 def setup_env(env, param_set) # put new layer _env = env.layer # set current package id _env.set(current_package_id: package_id) # merge parameter set _env.merge_param_set(param_set) ### system environment # ENV.each do |key, value| # @variable_table.set(Variable.new("ENV_" + key), PioneString.new(value)) # end end |
#show_outputs(outputs) ⇒ Object
Show output tuples as message. This method is used for debugging only.
258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 258 def show_outputs(outputs) ("Result of %s:" % @digest) if outputs outputs.each_with_index do |output, i| output.each_with_index do |t, ii| ("[%s,%s] %s" % [i, ii, t.name], 1) end end else ("no outputs", 1) end end |
#update_time_by_touch_operation(tuples) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 207 def update_time_by_touch_operation(tuples) fun = lambda do |tuple| time = Time.now new_data = TupleSpace::DataTuple.new(name: tuple.name, domain: @domain_id, location: tuple.location, time: time) write(TupleSpace::TouchTuple.new(name: tuple.name, domain: @domain_id, time: time)) write(new_data) new_data end tuples.map do |tuple| take!(TupleSpace::DataTuple.new(name: tuple.name, domain: @domain_id)) ? fun.call(tuple) : tuple end end |
#write_data_null(output, tuples, i) ⇒ Object
Write a data null tuple if the output condition accepts nonexistence.
221 222 223 224 225 |
# File 'lib/pione/rule-engine/basic-handler.rb', line 221 def write_data_null(output, tuples, i) if output.accept_nonexistence? and tuples.nil? write(TupleSpace::DataNullTuple.new(domain: @domain_id, position: i)) end end |