pione 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/History.txt +11 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/bin/pione-log +5 -0
- data/example/CountChar/CountChar.pione +1 -1
- data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +39 -38
- data/lib/pione.rb +14 -35
- data/lib/pione/agent/input-generator.rb +38 -40
- data/lib/pione/agent/logger.rb +52 -19
- data/lib/pione/agent/rule-provider.rb +5 -8
- data/lib/pione/agent/task-worker.rb +25 -32
- data/lib/pione/agent/tuple-space-client.rb +22 -14
- data/lib/pione/command.rb +21 -0
- data/lib/pione/command/basic-command.rb +267 -84
- data/lib/pione/command/child-process.rb +21 -18
- data/lib/pione/command/daemon-process.rb +9 -8
- data/lib/pione/command/front-owner-command.rb +8 -25
- data/lib/pione/command/pione-broker.rb +27 -24
- data/lib/pione/command/pione-clean.rb +6 -6
- data/lib/pione/command/pione-client.rb +143 -128
- data/lib/pione/command/pione-log.rb +61 -0
- data/lib/pione/command/pione-relay-account-db.rb +40 -38
- data/lib/pione/command/pione-relay-client-db.rb +38 -42
- data/lib/pione/command/pione-relay.rb +19 -20
- data/lib/pione/command/pione-syntax-checker.rb +70 -45
- data/lib/pione/command/pione-task-worker.rb +56 -66
- data/lib/pione/command/pione-tuple-space-provider.rb +36 -45
- data/lib/pione/command/pione-tuple-space-receiver.rb +34 -32
- data/lib/pione/command/pione-tuple-space-viewer.rb +63 -47
- data/lib/pione/location.rb +10 -0
- data/lib/pione/location/basic-location.rb +272 -0
- data/lib/pione/location/dropbox-location.rb +139 -0
- data/lib/pione/location/ftp-location.rb +156 -0
- data/lib/pione/location/local-location.rb +116 -0
- data/lib/pione/log.rb +10 -0
- data/lib/pione/log/domain-info.rb +72 -0
- data/lib/pione/log/process-log.rb +176 -0
- data/lib/pione/log/process-record.rb +189 -0
- data/lib/pione/log/xes-log.rb +105 -0
- data/lib/pione/model/assignment.rb +88 -80
- data/lib/pione/model/binary-operator.rb +74 -68
- data/lib/pione/model/block.rb +218 -207
- data/lib/pione/model/boolean.rb +123 -112
- data/lib/pione/model/call-rule.rb +72 -65
- data/lib/pione/model/data-expr.rb +596 -290
- data/lib/pione/model/float.rb +108 -103
- data/lib/pione/model/integer.rb +133 -129
- data/lib/pione/model/message.rb +79 -72
- data/lib/pione/model/package.rb +42 -38
- data/lib/pione/model/parameters.rb +265 -236
- data/lib/pione/model/rule-expr.rb +247 -242
- data/lib/pione/model/rule-io.rb +137 -133
- data/lib/pione/model/rule.rb +307 -292
- data/lib/pione/model/string.rb +110 -99
- data/lib/pione/model/variable-table.rb +300 -271
- data/lib/pione/model/variable.rb +88 -83
- data/lib/pione/option.rb +13 -0
- data/lib/pione/option/child-process-option.rb +19 -0
- data/lib/pione/{command-option → option}/common-option.rb +6 -5
- data/lib/pione/option/option-interface.rb +73 -0
- data/lib/pione/{command-option → option}/presence-notifier-option.rb +4 -3
- data/lib/pione/option/task-worker-owner-option.rb +24 -0
- data/lib/pione/{command-option → option}/tuple-space-provider-option.rb +6 -4
- data/lib/pione/option/tuple-space-provider-owner-option.rb +18 -0
- data/lib/pione/option/tuple-space-receiver-option.rb +8 -0
- data/lib/pione/parser/common-parser.rb +3 -2
- data/lib/pione/parser/expr-parser.rb +6 -1
- data/lib/pione/patch/em-ftpd-patch.rb +21 -0
- data/lib/pione/patch/rinda-patch.rb +31 -23
- data/lib/pione/rule-handler/action-handler.rb +35 -25
- data/lib/pione/rule-handler/basic-handler.rb +92 -18
- data/lib/pione/rule-handler/flow-handler.rb +104 -98
- data/lib/pione/rule-handler/root-handler.rb +11 -0
- data/lib/pione/system/common.rb +10 -0
- data/lib/pione/system/file-cache.rb +103 -84
- data/lib/pione/system/global.rb +67 -12
- data/lib/pione/system/init.rb +20 -0
- data/lib/pione/transformer/expr-transformer.rb +6 -1
- data/lib/pione/tuple-space/data-finder.rb +33 -6
- data/lib/pione/tuple-space/tuple-space-receiver.rb +4 -3
- data/lib/pione/tuple-space/tuple-space-server-interface.rb +58 -13
- data/lib/pione/tuple-space/tuple-space-server.rb +13 -11
- data/lib/pione/tuple-space/update-criteria.rb +8 -7
- data/lib/pione/tuple/base-location-tuple.rb +9 -0
- data/lib/pione/tuple/basic-tuple.rb +7 -7
- data/lib/pione/tuple/data-tuple.rb +5 -2
- data/lib/pione/tuple/lift-tuple.rb +14 -0
- data/lib/pione/tuple/rule-tuple.rb +1 -1
- data/lib/pione/tuple/task-tuple.rb +5 -1
- data/lib/pione/version.rb +1 -1
- data/pione.gemspec +5 -1
- data/test/location/spec_basic-location.rb +35 -0
- data/test/location/spec_ftp-location.rb +100 -0
- data/test/location/spec_local-location.rb +99 -0
- data/test/log/data/sample.log +1003 -0
- data/test/log/spec_xes-log.rb +11 -0
- data/test/model/spec_data-expr.rb +249 -6
- data/test/model/spec_data-expr.yml +45 -0
- data/test/parser/spec_expr-parser.yml +4 -0
- data/test/spec_data-finder.rb +13 -7
- data/test/spec_data-finder.yml +42 -13
- data/test/system/spec_file-cache.rb +39 -0
- data/test/test-util.rb +226 -1
- data/test/transformer/spec_expr-transformer.rb +12 -1
- metadata +107 -24
- data/bin/pione-search-log +0 -30
- data/lib/pione/command-option/basic-option.rb +0 -42
- data/lib/pione/command-option/child-process-option.rb +0 -17
- data/lib/pione/command-option/daemon-option.rb +0 -12
- data/lib/pione/command-option/task-worker-owner-option.rb +0 -17
- data/lib/pione/command-option/tuple-space-provider-owner-option.rb +0 -16
- data/lib/pione/command-option/tuple-space-receiver-option.rb +0 -12
- data/lib/pione/command/tuple-space-provider-owner.rb +0 -6
- data/lib/pione/resource/basic-resource.rb +0 -92
- data/lib/pione/resource/dropbox-resource.rb +0 -106
- data/lib/pione/resource/ftp.rb +0 -84
- data/lib/pione/resource/local.rb +0 -113
- data/lib/pione/tuple/base-uri-tuple.rb +0 -9
- data/lib/pione/tuple/shift-tuple.rb +0 -13
- data/lib/pione/util/log.rb +0 -79
- data/test/spec_resource.rb +0 -73
@@ -1,11 +1,11 @@
|
|
1
1
|
module Pione
|
2
2
|
module Agent
|
3
|
+
# RuleProvider is an agent for providing rules to other agents.
|
3
4
|
class RuleProvider < TupleSpaceClient
|
4
|
-
|
5
5
|
set_agent_type :rule_provider
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
super(
|
7
|
+
def initialize(tuple_space_server)
|
8
|
+
super(tuple_space_server)
|
9
9
|
@table = {}
|
10
10
|
|
11
11
|
# import system rules
|
@@ -44,14 +44,11 @@ module Pione
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def transit_to_rule_loading(request)
|
47
|
-
out = Tuple[:rule].new(rule_path: request.rule_path)
|
48
47
|
if known_rule?(request.rule_path)
|
49
|
-
|
50
|
-
out.content = @table[request.rule_path]
|
48
|
+
write(Tuple[:rule].new(rule_path: request.rule_path, content: @table[request.rule_path]))
|
51
49
|
else
|
52
|
-
|
50
|
+
processing_error("rule '%s' is unknonw" % request.rule_path)
|
53
51
|
end
|
54
|
-
write(out)
|
55
52
|
end
|
56
53
|
|
57
54
|
def known_rule?(rule_path)
|
@@ -106,13 +106,11 @@ module Pione
|
|
106
106
|
|
107
107
|
# Transition method for the state +task_waiting+. The agent takes a +task+
|
108
108
|
# tuple and writes a +working+ tuple.
|
109
|
+
#
|
109
110
|
# @return [Task]
|
110
111
|
# task tuple
|
111
112
|
def transit_to_task_waiting
|
112
|
-
@task = nil
|
113
|
-
@rule = nil
|
114
113
|
task = take(Tuple[:task].new(features: @features))
|
115
|
-
@task = task
|
116
114
|
begin
|
117
115
|
write(Tuple[:working].new(task.domain, task.digest))
|
118
116
|
write(Tuple[:foreground].new(task.domain, task.digest))
|
@@ -126,23 +124,12 @@ module Pione
|
|
126
124
|
# @return [Array<Task, Rule>]
|
127
125
|
# task tuple and the rule
|
128
126
|
def transit_to_rule_loading(task)
|
129
|
-
rule =
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
log do |msg|
|
134
|
-
msg.add_record(agent_type, "action", "request_rule")
|
135
|
-
msg.add_record(agent_type, "object", task.rule_path)
|
136
|
-
end
|
137
|
-
write(Tuple[:request_rule].new(task.rule_path))
|
138
|
-
read(Tuple[:rule].new(rule_path: task.rule_path))
|
139
|
-
end
|
140
|
-
@rule = rule.content
|
141
|
-
if rule.status == :known
|
142
|
-
return task, rule.content
|
143
|
-
else
|
144
|
-
raise UnknownRuleError.new(task)
|
127
|
+
rule = read!(Tuple[:rule].new(rule_path: task.rule_path))
|
128
|
+
unless rule
|
129
|
+
write(Tuple[:request_rule].new(task.rule_path))
|
130
|
+
rule = read(Tuple[:rule].new(rule_path: task.rule_path))
|
145
131
|
end
|
132
|
+
return task, rule.content
|
146
133
|
end
|
147
134
|
|
148
135
|
# Transition method for the state +task_executing+.
|
@@ -177,13 +164,16 @@ module Pione
|
|
177
164
|
debug_message "+++ Create Sub Task worker +++"
|
178
165
|
@child_agent = self.class.new(tuple_space_server, @features)
|
179
166
|
@child_agent.once = true
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
167
|
+
|
168
|
+
Log::CreateChildTaskWorkerProcessRecord.new.tap do |record|
|
169
|
+
record.parent = uuid
|
170
|
+
record.child = @child_agent.uuid
|
171
|
+
|
172
|
+
with_process_log(record) do
|
173
|
+
take!(Tuple[:foreground].new(task.domain, nil))
|
174
|
+
@child_agent.start
|
175
|
+
end
|
184
176
|
end
|
185
|
-
take0(Tuple[:foreground].new(task.domain, nil)) rescue true
|
186
|
-
@child_agent.start
|
187
177
|
else
|
188
178
|
tail = descendant.last
|
189
179
|
if tail.action?
|
@@ -209,7 +199,7 @@ module Pione
|
|
209
199
|
@action = nil
|
210
200
|
|
211
201
|
# remove the working tuple
|
212
|
-
|
202
|
+
take!(Tuple[:working].new(task.domain, nil))
|
213
203
|
|
214
204
|
debug_message_end "End Task Execution #{rule.rule_path} by worker(#{uuid})"
|
215
205
|
|
@@ -245,16 +235,19 @@ module Pione
|
|
245
235
|
# the handler
|
246
236
|
# @return [void]
|
247
237
|
def transit_to_task_finishing(task, handler)
|
248
|
-
|
249
|
-
msg.add_record(agent_type, "action", "finished_task")
|
250
|
-
msg.add_record(agent_type, "uuid", uuid)
|
251
|
-
msg.add_record(agent_type, "object", task)
|
252
|
-
end
|
238
|
+
# put finished tuple
|
253
239
|
finished = Tuple[:finished].new(
|
254
240
|
handler.domain, :succeeded, handler.outputs, task.digest
|
255
241
|
)
|
256
242
|
write(finished)
|
257
|
-
|
243
|
+
# log task process
|
244
|
+
record = handler.task_process_record.merge(transition: "complete")
|
245
|
+
process_log(record)
|
246
|
+
|
247
|
+
# remove foreground
|
248
|
+
take!(Tuple[:foreground].new(task.domain, nil))
|
249
|
+
|
250
|
+
# terminate if the agent is child
|
258
251
|
terminate if @once
|
259
252
|
end
|
260
253
|
|
@@ -43,6 +43,10 @@ module Pione
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
def base_location
|
47
|
+
read(Tuple[:base_location].any).location
|
48
|
+
end
|
49
|
+
|
46
50
|
# Protected take.
|
47
51
|
def take(*args)
|
48
52
|
tuple = super(*args, &method(:set_current_tuple_entry))
|
@@ -114,32 +118,36 @@ module Pione
|
|
114
118
|
|
115
119
|
# Redefine hello method with logging.
|
116
120
|
def hello
|
117
|
-
|
118
|
-
|
119
|
-
|
121
|
+
record = Log::AgentConnectionProcessRecord.new.tap do |record|
|
122
|
+
record.agent_type = agent_type
|
123
|
+
record.agent_uuid = uuid
|
124
|
+
record.message = "hello"
|
120
125
|
end
|
121
|
-
super
|
126
|
+
with_process_log(record) {super}
|
122
127
|
end
|
123
128
|
|
124
129
|
# Redefine bye method with logging.
|
125
130
|
def bye
|
126
|
-
|
127
|
-
|
128
|
-
|
131
|
+
record = Log::AgentConnectionProcessRecord.new.tap do |record|
|
132
|
+
record.agent_type = agent_type
|
133
|
+
record.agent_uuid = uuid
|
134
|
+
record.message = "bye"
|
129
135
|
end
|
130
|
-
super
|
136
|
+
with_process_log(record) {super}
|
131
137
|
end
|
132
138
|
|
133
|
-
#
|
139
|
+
# Override call transition method with logging.
|
134
140
|
def call_transition_method(*args)
|
135
141
|
unless [:logger, :command_listener].include?(agent_type)
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
142
|
+
record = Log::AgentActivityProcessRecord.new.tap do |rec|
|
143
|
+
rec.agent_type = agent_type
|
144
|
+
rec.agent_uuid = uuid
|
145
|
+
rec.state = args.first
|
140
146
|
end
|
147
|
+
with_process_log(record) {super}
|
148
|
+
else
|
149
|
+
super
|
141
150
|
end
|
142
|
-
super
|
143
151
|
end
|
144
152
|
end
|
145
153
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Pione
|
2
|
+
# Command is a name space for PIONE command classes.
|
3
|
+
module Command; end
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'pione/command/basic-command'
|
7
|
+
require 'pione/command/front-owner-command'
|
8
|
+
require 'pione/command/daemon-process'
|
9
|
+
require 'pione/command/child-process'
|
10
|
+
require 'pione/command/pione-client'
|
11
|
+
require 'pione/command/pione-task-worker'
|
12
|
+
require 'pione/command/pione-broker'
|
13
|
+
require 'pione/command/pione-tuple-space-provider'
|
14
|
+
require 'pione/command/pione-tuple-space-receiver'
|
15
|
+
require 'pione/command/pione-tuple-space-viewer'
|
16
|
+
require 'pione/command/pione-relay'
|
17
|
+
require 'pione/command/pione-relay-client-db'
|
18
|
+
require 'pione/command/pione-relay-account-db'
|
19
|
+
require 'pione/command/pione-clean'
|
20
|
+
require 'pione/command/pione-syntax-checker'
|
21
|
+
require 'pione/command/pione-log'
|
@@ -1,132 +1,315 @@
|
|
1
1
|
module Pione
|
2
2
|
module Command
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
# CommandInfo is a strage of program informations.
|
4
|
+
class CommandInfo
|
5
|
+
attr_reader :name
|
6
|
+
attr_reader :tail
|
7
|
+
attr_reader :banner
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@name = nil
|
11
|
+
@tail = nil
|
12
|
+
@banner = banner
|
8
13
|
end
|
9
14
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
# Set progaram name.
|
16
|
+
#
|
17
|
+
# @param name [String]
|
18
|
+
# process name
|
19
|
+
# @param b [Proc]
|
20
|
+
# process tail block
|
21
|
+
# @return [void]
|
22
|
+
def set_name(name, &b)
|
23
|
+
@name = name
|
14
24
|
end
|
15
25
|
|
16
|
-
#
|
17
|
-
def
|
18
|
-
@
|
26
|
+
# Set program parameters.
|
27
|
+
def set_tail(&tail)
|
28
|
+
@tail = tail
|
19
29
|
end
|
20
30
|
|
21
|
-
#
|
22
|
-
|
23
|
-
|
31
|
+
# Set program banner.
|
32
|
+
#
|
33
|
+
# @param banner [String]
|
34
|
+
# banner message
|
35
|
+
# @return [void]
|
36
|
+
def set_banner(banner)
|
37
|
+
@banner = banner
|
24
38
|
end
|
25
|
-
end
|
26
39
|
|
27
|
-
module InstanceInterface
|
28
40
|
# Setup program name. If the setup process is failed, program name is not
|
29
41
|
# changed.
|
30
42
|
#
|
43
|
+
# @param cmd [BasicCommand]
|
44
|
+
# command
|
31
45
|
# @return [void]
|
32
|
-
def
|
33
|
-
|
34
|
-
name, b = self.class.program_name
|
35
|
-
tail = self.instance_exec(&b)
|
36
|
-
$PROGRAM_NAME = "%s %s" % [name, tail]
|
37
|
-
rescue Exception
|
38
|
-
nil
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns program message.
|
43
|
-
# @return [String]
|
44
|
-
# program message
|
45
|
-
def program_message
|
46
|
-
self.class.program_message
|
46
|
+
def setup(cmd)
|
47
|
+
$PROGRAM_NAME = "%s %s" % [@name, @tail ? @tail.call(cmd) : ""]
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
#
|
51
|
-
class
|
52
|
-
|
53
|
-
include InstanceInterface
|
54
|
-
extend CommandOption::OptionInterface
|
55
|
-
use_option_module CommandOption::CommonOption
|
51
|
+
# CommandOption is a class for holding option data set.
|
52
|
+
class CommandOption < PioneObject
|
53
|
+
def_delegators :@data, :[], :[]=
|
56
54
|
|
57
|
-
#
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
self.new(*args).run
|
66
|
-
end
|
67
|
-
|
68
|
-
# Runs the command.
|
69
|
-
def run
|
70
|
-
parse_options
|
71
|
-
validate_options
|
72
|
-
prepare
|
73
|
-
setup_program_name
|
74
|
-
start
|
55
|
+
# Creata a command option context.
|
56
|
+
#
|
57
|
+
# @param command_info [CommandInfo]
|
58
|
+
# command informations
|
59
|
+
def initialize(command_info)
|
60
|
+
extend Option::OptionInterface
|
61
|
+
@command_info = command_info
|
62
|
+
@data = {}
|
75
63
|
end
|
76
64
|
|
77
|
-
|
78
|
-
|
79
|
-
# Parses options.
|
65
|
+
# Parse the command options.
|
66
|
+
#
|
80
67
|
# @return [void]
|
81
|
-
def
|
82
|
-
|
68
|
+
def parse
|
69
|
+
OptionParser.new do |opt|
|
70
|
+
# set banner
|
83
71
|
opt.banner = "Usage: %s [options]" % opt.program_name
|
84
|
-
opt.banner << "\n" +
|
72
|
+
opt.banner << "\n" + @command_info.banner if @command_info.banner
|
85
73
|
|
86
|
-
|
87
|
-
opt.on(*args, Proc.new{|*args| self.instance_exec(*args, &b)})
|
88
|
-
end
|
74
|
+
# set version
|
89
75
|
opt.version = Pione::VERSION
|
90
|
-
end
|
91
76
|
|
92
|
-
|
77
|
+
# set default values
|
78
|
+
default_table.each do |key, value|
|
79
|
+
@data[key] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
# set options
|
83
|
+
definitions.sort{|a,b| a.first <=> b.first}.each do |args, b|
|
84
|
+
opt.on(*args, Proc.new{|*args| self.instance_exec(@data, *args, &b)})
|
85
|
+
end
|
86
|
+
end.parse!(ARGV)
|
93
87
|
rescue OptionParser::InvalidOption => e
|
94
|
-
e.args.each {|arg| $stderr.puts "Unknown option:
|
88
|
+
e.args.each {|arg| $stderr.puts "Unknown option: %s" % arg }
|
95
89
|
abort
|
96
90
|
rescue OptionParser::MissingArgument => e
|
97
91
|
abort(e.message)
|
98
92
|
end
|
99
93
|
|
100
|
-
#
|
101
|
-
#
|
94
|
+
# Check validness of the command options.
|
95
|
+
#
|
102
96
|
# @return [void]
|
103
|
-
def
|
104
|
-
|
97
|
+
def check
|
98
|
+
validators.each do |validator|
|
99
|
+
validator.call(@data)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# BasicCommand is a base class for PIONE commands.
|
105
|
+
class BasicCommand < PioneObject
|
106
|
+
@info = CommandInfo.new
|
107
|
+
@option = CommandOption.new(@info).tap {|x| x.use Option::CommonOption}
|
108
|
+
@pre_preparations = []
|
109
|
+
@preparations = []
|
110
|
+
@post_preparations = []
|
111
|
+
@pre_starts = []
|
112
|
+
@starts = []
|
113
|
+
@post_starts = []
|
114
|
+
@pre_terminations = []
|
115
|
+
@terminations = []
|
116
|
+
@post_terminations =[]
|
117
|
+
|
118
|
+
class << self
|
119
|
+
attr_reader :info
|
120
|
+
attr_reader :option
|
121
|
+
attr_reader :pre_preparations
|
122
|
+
attr_reader :preparations
|
123
|
+
attr_reader :post_preparations
|
124
|
+
attr_reader :pre_starts
|
125
|
+
attr_reader :starts
|
126
|
+
attr_reader :post_starts
|
127
|
+
attr_reader :pre_terminations
|
128
|
+
attr_reader :terminations
|
129
|
+
attr_reader :post_terminations
|
130
|
+
|
131
|
+
# @api private
|
132
|
+
def inherited(subclass)
|
133
|
+
parent_option = self.option
|
134
|
+
subclass.instance_eval do
|
135
|
+
@info = CommandInfo.new
|
136
|
+
@option = CommandOption.new(@info).tap {|x| x.use parent_option}
|
137
|
+
end
|
138
|
+
setter = lambda{|name, data| subclass.instance_variable_set(name, data.clone)}
|
139
|
+
setter.call(:@pre_preparations, self.pre_preparations)
|
140
|
+
setter.call(:@preparations, self.preparations)
|
141
|
+
setter.call(:@post_preparations, self.post_preparations)
|
142
|
+
setter.call(:@pre_starts, self.pre_starts)
|
143
|
+
setter.call(:@starts, self.starts)
|
144
|
+
setter.call(:@post_starts, self.post_starts)
|
145
|
+
setter.call(:@pre_terminations, self.pre_terminations)
|
146
|
+
setter.call(:@terminations, self.terminations)
|
147
|
+
setter.call(:@post_terminations, self.post_terminations)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Define command informations.
|
151
|
+
#
|
152
|
+
# @param b [Proc]
|
153
|
+
# evaluation content in the context of option definition
|
154
|
+
# @return [void]
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# class Cmd < BasicCommand
|
158
|
+
# define_info do
|
159
|
+
# set_name "test" # set process name
|
160
|
+
# set_banner "sample" # set banner message
|
161
|
+
# end
|
162
|
+
# end
|
163
|
+
def define_info(&b)
|
164
|
+
@info.instance_eval(&b)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Define command option.
|
168
|
+
#
|
169
|
+
# @param b [Proc]
|
170
|
+
# context of the option definition
|
171
|
+
#
|
172
|
+
# @example
|
173
|
+
# class Cmd < BasicCommand
|
174
|
+
# define_option do
|
175
|
+
# option("-t", "--test", "test option") do |data, arg1|
|
176
|
+
# data[:test] = true
|
177
|
+
# end
|
178
|
+
# end
|
179
|
+
# end
|
180
|
+
def define_option(&b)
|
181
|
+
@option.instance_eval(&b)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Define a preparation process.
|
185
|
+
#
|
186
|
+
# @param type [Symbol]
|
187
|
+
# preparation type
|
188
|
+
# @return [void]
|
189
|
+
def prepare(type=nil, &b)
|
190
|
+
case type
|
191
|
+
when :pre
|
192
|
+
@pre_preparations << b
|
193
|
+
when :post
|
194
|
+
@post_preparations << b
|
195
|
+
else
|
196
|
+
@preparations << b
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Define a start process.
|
201
|
+
#
|
202
|
+
# @param type [Symbol]
|
203
|
+
# start type
|
204
|
+
# @return [void]
|
205
|
+
def start(type=nil, &b)
|
206
|
+
case type
|
207
|
+
when :pre
|
208
|
+
@pre_starts << b
|
209
|
+
when :post
|
210
|
+
@post_starts << b
|
211
|
+
else
|
212
|
+
@starts << b
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Define a termination process.
|
217
|
+
#
|
218
|
+
# @param type [Symbol]
|
219
|
+
# termination type
|
220
|
+
# @return [void]
|
221
|
+
def terminate(type=nil, &b)
|
222
|
+
case type
|
223
|
+
when :pre
|
224
|
+
@pre_terminations << b
|
225
|
+
when :post
|
226
|
+
@post_terminations << b
|
227
|
+
else
|
228
|
+
@terminations << b
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
# Run the command.
|
233
|
+
#
|
234
|
+
# @return [void]
|
235
|
+
def run(*args)
|
236
|
+
self.new(*args).run
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Return a command option.
|
241
|
+
#
|
242
|
+
# @return [CommandOption]
|
243
|
+
# command option
|
244
|
+
def option
|
245
|
+
self.class.option
|
105
246
|
end
|
106
247
|
|
107
|
-
#
|
108
|
-
#
|
248
|
+
# Return a command info.
|
249
|
+
#
|
250
|
+
# @return [CommandInfo]
|
251
|
+
# command info
|
252
|
+
def info
|
253
|
+
self.class.info
|
254
|
+
end
|
255
|
+
|
256
|
+
# Run the command.
|
257
|
+
#
|
109
258
|
# @return [void]
|
110
|
-
def
|
259
|
+
def run
|
260
|
+
receiver = self
|
261
|
+
caller = lambda {|name| self.class.__send__(name).each{|proc| receiver.instance_eval(&proc)}}
|
262
|
+
caller.call(:pre_preparations)
|
263
|
+
caller.call(:preparations)
|
264
|
+
caller.call(:post_preparations)
|
265
|
+
caller.call(:pre_starts)
|
266
|
+
caller.call(:starts)
|
267
|
+
caller.call(:post_starts)
|
268
|
+
call_terminations
|
269
|
+
end
|
270
|
+
|
271
|
+
def call_terminations
|
272
|
+
receiver = self
|
273
|
+
caller = lambda do |name|
|
274
|
+
self.class.__send__(name).reverse.each do |proc|
|
275
|
+
puts "%s(%s):%s:%s" % [info.name, name, *proc.source_location] if Pione.debug_mode?
|
276
|
+
begin
|
277
|
+
receiver.instance_eval(&proc)
|
278
|
+
rescue Object => e
|
279
|
+
p e
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
caller.call(:pre_terminations)
|
284
|
+
caller.call(:terminations)
|
285
|
+
caller.call(:post_terminations)
|
286
|
+
end
|
287
|
+
|
288
|
+
prepare(:pre) do
|
289
|
+
# set signal trap
|
111
290
|
Signal.trap(:INT) do
|
112
291
|
begin
|
113
|
-
|
292
|
+
call_terminations
|
114
293
|
rescue DRb::ReplyReaderThreadError
|
115
294
|
# ignore reply reader error
|
116
295
|
end
|
117
296
|
end
|
297
|
+
|
298
|
+
# parse options
|
299
|
+
option.parse
|
118
300
|
end
|
119
301
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
raise NotImplementedError
|
302
|
+
prepare do
|
303
|
+
# validate options
|
304
|
+
option.check
|
124
305
|
end
|
125
306
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
307
|
+
prepare(:post) do
|
308
|
+
# setup process name
|
309
|
+
info.setup(self)
|
310
|
+
end
|
311
|
+
|
312
|
+
terminate(:post) do
|
130
313
|
Global.monitor.synchronize do
|
131
314
|
# exit with no exception
|
132
315
|
exit!
|