pione 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/.gitignore +3 -2
  2. data/History.txt +6 -0
  3. data/Rakefile +1 -1
  4. data/bin/pione-broker +1 -1
  5. data/bin/pione-clean +1 -1
  6. data/bin/pione-client +1 -1
  7. data/bin/pione-log +1 -1
  8. data/bin/pione-relay +1 -1
  9. data/bin/pione-relay-account-db +1 -1
  10. data/bin/pione-relay-client-db +1 -1
  11. data/bin/pione-syntax-checker +1 -1
  12. data/bin/pione-task-worker +1 -1
  13. data/bin/pione-tuple-space-provider +1 -1
  14. data/bin/pione-tuple-space-receiver +1 -1
  15. data/bin/pione-tuple-space-viewer +1 -1
  16. data/bin/pione-val +1 -1
  17. data/example/CTFCorrection/CTFCorrection.pione +78 -0
  18. data/example/CTFCorrection/package.yml +1 -0
  19. data/example/HelloWorld/scenario/output/message.txt +1 -0
  20. data/example/LoopByTouch/LoopByTouch.pione +10 -18
  21. data/example/LoopByTouch/PairLoop.pione +18 -0
  22. data/example/LoopByTouch/SingleLoop.pione +5 -0
  23. data/example/LoopByTouch/TripletLoop.pione +24 -0
  24. data/example/MakePair/scenario/output/comb-1-2.pair +0 -0
  25. data/example/MakePair/scenario/output/comb-1-3.pair +0 -0
  26. data/example/MakePair/scenario/output/comb-1-4.pair +0 -0
  27. data/example/MakePair/scenario/output/comb-1-5.pair +0 -0
  28. data/example/MakePair/scenario/output/comb-2-3.pair +0 -0
  29. data/example/MakePair/scenario/output/comb-2-4.pair +0 -0
  30. data/example/MakePair/scenario/output/comb-2-5.pair +0 -0
  31. data/example/MakePair/scenario/output/comb-3-4.pair +0 -0
  32. data/example/MakePair/scenario/output/comb-3-5.pair +0 -0
  33. data/example/MakePair/scenario/output/comb-4-5.pair +0 -0
  34. data/example/MakePair/scenario/output/perm-1-2.pair +0 -0
  35. data/example/MakePair/scenario/output/perm-1-3.pair +0 -0
  36. data/example/MakePair/scenario/output/perm-1-4.pair +0 -0
  37. data/example/MakePair/scenario/output/perm-1-5.pair +0 -0
  38. data/example/MakePair/scenario/output/perm-2-1.pair +0 -0
  39. data/example/MakePair/scenario/output/perm-2-3.pair +0 -0
  40. data/example/MakePair/scenario/output/perm-2-4.pair +0 -0
  41. data/example/MakePair/scenario/output/perm-2-5.pair +0 -0
  42. data/example/MakePair/scenario/output/perm-3-1.pair +0 -0
  43. data/example/MakePair/scenario/output/perm-3-2.pair +0 -0
  44. data/example/MakePair/scenario/output/perm-3-4.pair +0 -0
  45. data/example/MakePair/scenario/output/perm-3-5.pair +0 -0
  46. data/example/MakePair/scenario/output/perm-4-1.pair +0 -0
  47. data/example/MakePair/scenario/output/perm-4-2.pair +0 -0
  48. data/example/MakePair/scenario/output/perm-4-3.pair +0 -0
  49. data/example/MakePair/scenario/output/perm-4-5.pair +0 -0
  50. data/example/MakePair/scenario/output/perm-5-1.pair +0 -0
  51. data/example/MakePair/scenario/output/perm-5-2.pair +0 -0
  52. data/example/MakePair/scenario/output/perm-5-3.pair +0 -0
  53. data/example/MakePair/scenario/output/perm-5-4.pair +0 -0
  54. data/example/MakePair/scenario/output/succ-1-2.pair +0 -0
  55. data/example/MakePair/scenario/output/succ-2-3.pair +0 -0
  56. data/example/MakePair/scenario/output/succ-3-4.pair +0 -0
  57. data/example/MakePair/scenario/output/succ-4-5.pair +0 -0
  58. data/example/SyntaxError/output_line_error.pione +6 -0
  59. data/example/WorkflowPatterns/38_GeneralSynchronizingMerge/GeneralSynchronizingMerge.pione +94 -0
  60. data/lib/pione.rb +1 -10
  61. data/lib/pione/agent/process-manager.rb +6 -5
  62. data/lib/pione/agent/rule-provider.rb +7 -9
  63. data/lib/pione/agent/task-worker.rb +1 -1
  64. data/lib/pione/command.rb +1 -0
  65. data/lib/pione/command/basic-command.rb +12 -77
  66. data/lib/pione/command/child-process.rb +19 -13
  67. data/lib/pione/command/daemon-process.rb +0 -9
  68. data/lib/pione/command/front-owner-command.rb +0 -6
  69. data/lib/pione/command/option.rb +243 -0
  70. data/lib/pione/command/pione-broker.rb +10 -5
  71. data/lib/pione/command/pione-clean.rb +4 -0
  72. data/lib/pione/command/pione-client.rb +257 -210
  73. data/lib/pione/command/pione-log.rb +38 -19
  74. data/lib/pione/command/pione-relay-account-db.rb +42 -17
  75. data/lib/pione/command/pione-relay-client-db.rb +35 -14
  76. data/lib/pione/command/pione-relay.rb +16 -8
  77. data/lib/pione/command/pione-syntax-checker.rb +33 -13
  78. data/lib/pione/command/pione-task-worker.rb +26 -23
  79. data/lib/pione/command/pione-tuple-space-provider.rb +8 -17
  80. data/lib/pione/command/pione-tuple-space-receiver.rb +13 -3
  81. data/lib/pione/command/pione-tuple-space-viewer.rb +42 -23
  82. data/lib/pione/command/pione-val.rb +15 -7
  83. data/lib/pione/component/document.rb +49 -70
  84. data/lib/pione/component/package.rb +125 -83
  85. data/lib/pione/location/basic-location.rb +1 -0
  86. data/lib/pione/model/assignment.rb +11 -0
  87. data/lib/pione/model/parameters.rb +10 -0
  88. data/lib/pione/model/variable.rb +14 -0
  89. data/lib/pione/parser/common-parser.rb +4 -0
  90. data/lib/pione/parser/document-parser.rb +4 -3
  91. data/lib/pione/parser/rule-definition-parser.rb +2 -1
  92. data/lib/pione/patch/rinda-patch.rb +1 -1
  93. data/lib/pione/rule-handler/action-handler.rb +6 -1
  94. data/lib/pione/rule-handler/basic-handler.rb +0 -6
  95. data/lib/pione/rule-handler/flow-handler.rb +14 -9
  96. data/lib/pione/system/global.rb +3 -0
  97. data/lib/pione/system/package-cache.rb +18 -0
  98. data/lib/pione/transformer/document-transformer.rb +26 -3
  99. data/lib/pione/transformer/rule-definition-transformer.rb +10 -2
  100. data/lib/pione/tuple-space/presence-notifier.rb +4 -3
  101. data/lib/pione/uri-scheme.rb +11 -0
  102. data/lib/pione/uri-scheme/git-scheme.rb +12 -0
  103. data/lib/pione/util.rb +2 -0
  104. data/lib/pione/util/package-parameters-list.rb +32 -0
  105. data/lib/pione/util/process-info.rb +21 -0
  106. data/lib/pione/version.rb +1 -1
  107. data/pione.gemspec +1 -1
  108. data/test/agent/spec_rule-provider.rb +57 -44
  109. data/test/command/command-behavior.rb +15 -0
  110. data/test/command/spec_pione-client.rb +56 -0
  111. data/test/command/spec_pione-val.domain.dump +0 -0
  112. data/test/command/spec_pione-val.rb +22 -0
  113. data/test/component/spec_document.pione +51 -0
  114. data/test/component/spec_document.rb +41 -70
  115. data/test/component/spec_package.rb +18 -3
  116. data/test/parser/spec_document-parser.yml +15 -0
  117. data/test/parser/spec_rule-definition-parser.yml +7 -2
  118. data/test/rule-handler/spec_action-handler.rb +6 -6
  119. data/test/rule-handler/spec_flow-handler.pione +25 -0
  120. data/test/rule-handler/spec_flow-handler.rb +35 -95
  121. data/test/rule-handler/spec_update-criteria.rb +2 -2
  122. data/test/test-util.rb +68 -4
  123. data/test/transformer/spec_block-transformer.rb +1 -1
  124. data/test/transformer/spec_document-transformer.rb +50 -0
  125. data/test/transformer/spec_expr-transformer.rb +1 -1
  126. data/test/transformer/spec_flow-element-transformer.rb +13 -13
  127. data/test/transformer/spec_literal-transformer.rb +1 -1
  128. data/test/transformer/spec_rule-definition-transformer.rb +31 -19
  129. data/test/uri-scheme/spec_git-scheme.rb +20 -0
  130. data/test/util/spec_id.rb +6 -6
  131. data/test/util/spec_package-parameters-list.rb +59 -0
  132. data/test/util/spec_package-parameters-list_1.pione +17 -0
  133. data/test/util/spec_package-parameters-list_2.pione +13 -0
  134. data/test/util/spec_package-parameters-list_3.pione +12 -0
  135. data/test/util/spec_package-parameters-list_4.pione +6 -0
  136. data/test/util/spec_process-info.rb +56 -0
  137. metadata +79 -16
  138. data/lib/pione/option.rb +0 -13
  139. data/lib/pione/option/child-process-option.rb +0 -19
  140. data/lib/pione/option/common-option.rb +0 -31
  141. data/lib/pione/option/option-interface.rb +0 -73
  142. data/lib/pione/option/presence-notifier-option.rb +0 -16
  143. data/lib/pione/option/task-worker-owner-option.rb +0 -24
  144. data/lib/pione/option/tuple-space-provider-option.rb +0 -28
  145. data/lib/pione/option/tuple-space-provider-owner-option.rb +0 -18
  146. data/lib/pione/option/tuple-space-receiver-option.rb +0 -8
@@ -10,11 +10,16 @@ module Pione
10
10
  end
11
11
 
12
12
  define_option do
13
- use Option::TupleSpaceReceiverOption
14
- use Option::TaskWorkerOwnerOption
15
-
16
- validate do |data|
17
- unless data[:task_worker] > 0
13
+ use :color
14
+ use :daemon
15
+ use :debug
16
+ use :features
17
+ use :my_ip_address
18
+ use :show_communication
19
+ use :task_worker
20
+
21
+ validate do |option|
22
+ unless option[:task_worker] > 0
18
23
  abort("error: no task worker resources")
19
24
  end
20
25
  end
@@ -7,6 +7,10 @@ module Pione
7
7
  set_banner "Clean working directories and file cache directories."
8
8
  end
9
9
 
10
+ define_option do
11
+ use :debug
12
+ end
13
+
10
14
  start do
11
15
  FileUtils.remove_entry_secure(Global.working_directory_root)
12
16
  FileUtils.remove_entry_secure(Global.file_cache_directory_root)
@@ -2,114 +2,137 @@ module Pione
2
2
  module Command
3
3
  # PioneClient is a command to request processing.
4
4
  class PioneClient < FrontOwnerCommand
5
+ include TupleSpaceServerInterface
6
+
5
7
  define_info do
6
8
  set_name "pione-client"
7
- set_tail {|cmd|
8
- args = [cmd.option[:filename], cmd.option[:output_uri], cmd.option[:stream]]
9
- "{Document: %s, OutputURI: %s, Stream: %s}" % args
10
- }
9
+ set_tail {|cmd| Global.front.uri}
11
10
  set_banner "Requests to process PIONE document."
12
11
  end
13
12
 
14
13
  define_option do
15
- use Option::TaskWorkerOwnerOption
16
- use Option::TupleSpaceProviderOwnerOption
17
-
18
- default :output_location, Location["local:./output/"]
19
- default :stream, false
20
- default :params, Model::Parameters.empty
21
- default :dry_run, false
22
- default :task_worker, Agent::TaskWorker.default_number
23
- default :request_task_worker, 1
24
- default :stand_alone, false
25
- default :relay, nil
26
- default :filename, "-"
27
- default :without_tuple_space_provider, false
28
- default :features, "^Interactive"
29
- default :list_params, false
30
-
31
- # --input
32
- option('-i LOCATION', '--input=LOCATION', 'set input directory') do |data, uri|
33
- begin
34
- data[:input_location] = Location[uri]
35
- rescue ArgumentError
36
- abort("opiton error: bad location '%s'" % uri)
14
+ use :debug
15
+ use :color
16
+ use :show_communication
17
+ use :my_ip_address
18
+ use :presence_notification_address
19
+ use :show_presence_notifier
20
+ use :task_worker
21
+ use :features
22
+
23
+ define(:input_location) do |item|
24
+ item.short = '-i LOCATION'
25
+ item.long = '--input=LOCATION'
26
+ item.desc = 'set input directory'
27
+ item.value = proc do |uri|
28
+ begin
29
+ Location[uri]
30
+ rescue ArgumentError
31
+ abort("ERROR: bad location '%s'" % uri)
32
+ end
37
33
  end
38
34
  end
39
35
 
40
- # --output
41
- option('-o LOCATION', '--output=LOCATION', 'set output directory') do |data, uri|
42
- begin
43
- data[:output_location] = Location[uri]
44
- if URI.parse(uri).scheme == "myftp"
45
- data[:myftp] = URI.parse(uri).normalize
36
+ define(:output_location) do |item|
37
+ item.short = '-o LOCATION'
38
+ item.long = '--output=LOCATION'
39
+ item.desc = 'set output directory'
40
+ item.default = Location["local:./output/"]
41
+ item.action = proc do |option, uri|
42
+ begin
43
+ option[:output_location] = Location[uri]
44
+ if URI.parse(uri).scheme == "myftp"
45
+ option[:myftp] = URI.parse(uri).normalize
46
+ end
47
+ rescue ArgumentError
48
+ abort("ERROR: bad location '%s'" % uri)
46
49
  end
47
- rescue ArgumentError
48
- abort("opiton error: bad location '%s'" % uri)
49
50
  end
50
51
  end
51
52
 
52
- # --stream
53
- option('--stream', 'turn on stream mode') do |data|
54
- data[:stream] = true
53
+ define(:stream) do |item|
54
+ item.long = '--stream'
55
+ item.desc = 'turn on stream mode'
56
+ item.default = false
57
+ item.value = true
55
58
  end
56
59
 
57
- # --request-task-worker
58
- option('--request-task-worker=N', 'set request number of task workers') do |data, n|
59
- data[:request_task_worker] = n.to_i
60
+ define(:request_task_worker) do |item|
61
+ item.long = '--request-task-worker=N'
62
+ item.desc = 'set request number of task workers'
63
+ item.default = 1
64
+ item.value = proc {|n| n.to_i}
60
65
  end
61
66
 
62
- # --params
63
- option('--params="{Var:1,...}"', "set &main:Main rule's parameters") do |data, str|
64
- begin
65
- params = DocumentTransformer.new.apply(
66
- DocumentParser.new.parameters.parse(str)
67
- )
68
- data[:params].merge!(params)
69
- rescue Parslet::ParseFailed => e
70
- puts "invalid parameters: " + str
71
- Util::ErrorReport.print(e)
72
- abort
67
+ define(:params) do |item|
68
+ item.long = '--params="{Var:1,...}"'
69
+ item.desc = "set user parameters"
70
+ item.default = Model::Parameters.empty
71
+ item.action = proc do |option, str|
72
+ begin
73
+ params = DocumentTransformer.new.apply(
74
+ DocumentParser.new.parameters.parse(str)
75
+ )
76
+ option[:params].merge!(params)
77
+ rescue Parslet::ParseFailed => e
78
+ $stderr.puts "invalid parameters: " + str
79
+ Util::ErrorReport.print(e)
80
+ abort
81
+ end
73
82
  end
74
83
  end
75
84
 
76
- # --stand-alone
77
- option('--stand-alone', 'turn on stand alone mode') do |data|
78
- data[:stand_alone] = true
79
- data[:without_tuple_space_provider] = true
85
+ define(:stand_alone) do |item|
86
+ item.long = '--stand-alone'
87
+ item.desc = 'turn on stand alone mode'
88
+ item.default = false
89
+ item.action = proc do |option|
90
+ option[:stand_alone] = true
91
+ option[:without_tuple_space_provider] = true
92
+ end
80
93
  end
81
94
 
82
- # --dry-run
83
- option('--dry-run', 'turn on dry run mode') do |data, b|
84
- data[:dry_run] = true
95
+ define(:dry_run) do |item|
96
+ item.long = '--dry-run'
97
+ item.desc = 'turn on dry run mode'
98
+ item.default = false
99
+ item.value = true
85
100
  end
86
101
 
87
- # --relay
88
- option('--relay=URI', 'turn on relay mode and set relay address') do |data, uri|
89
- data[:relay] = uri
102
+ item(:features).default = "^Interactive"
103
+
104
+ define(:relay) do |item|
105
+ item.long = '--relay=URI'
106
+ item.desc = 'turn on relay mode and set relay address'
107
+ item.default = nil
108
+ item.value = proc {|uri| uri}
90
109
  end
91
110
 
92
- # --name
93
- option('--name=NAME') do |data, name|
94
- data[:name] = name
111
+ define(:list_params) do |item|
112
+ item.long = '--list-params'
113
+ item.desc = 'show user parameter list in the document'
114
+ item.value = true
95
115
  end
96
116
 
97
- # --list-parameters
98
- option('--list-params', 'show user parameter list in the document') do |data|
99
- data[:list_params] = true
117
+ define(:rehearse) do |item|
118
+ item.long = '--rehearse[=SCENARIO]'
119
+ item.desc = 'rehearse the scenario'
120
+ item.value = proc {|scenario_name| scenario_name || :anything}
100
121
  end
101
122
 
102
- option('--rehearse[=SCENARIO]', 'rehearse the scenario') do |data, scenario_name|
103
- data[:rehearse] = scenario_name || :anything
123
+ define(:without_tuple_space_provider) do |item|
124
+ item.long = '--without-tuple-space-provider'
125
+ item.desc = 'process without tuple space provider'
126
+ item.value = true
104
127
  end
105
128
 
106
- validate do |data|
107
- unless data[:task_worker] > 0 or
108
- (not(data[:stand_alone]) and data[:task_worker] == 0)
109
- abort("option error: invalid resource size '%s'" % data[:task_worker])
129
+ validate do |option|
130
+ unless option[:task_worker] > 0 or
131
+ (not(option[:stand_alone]) and option[:task_worker] == 0)
132
+ abort("option error: invalid resource size '%s'" % option[:task_worker])
110
133
  end
111
134
 
112
- if data[:stream] and data[:input_location].nil?
135
+ if option[:stream] and option[:input_location].nil?
113
136
  abort("option error: no input URI on stream mode")
114
137
  end
115
138
  end
@@ -118,12 +141,12 @@ module Pione
118
141
  attr_reader :task_worker
119
142
  attr_reader :features
120
143
  attr_reader :tuple_space_server
121
- attr_reader :name
122
144
 
123
- def initialize
124
- super()
145
+ def initialize(*options)
146
+ super(*options)
125
147
  @worker_threads = []
126
148
  @tuple_space_server = nil
149
+ @child_process_infos = []
127
150
  end
128
151
 
129
152
  private
@@ -133,93 +156,71 @@ module Pione
133
156
  end
134
157
 
135
158
  prepare do
136
- @filename = ARGF.filename
137
-
138
- # ftp server
139
- if myftp = option[:myftp]
140
- location = Location[myftp.path]
141
- location.path.mkdir unless location.exist?
142
- if myftp.userinfo
143
- Util::FTPServer.auth_info = Util::FTPAuthInfo.new(myftp.user, myftp.password)
144
- end
145
- if myftp.port
146
- Util::FTPServer.port = myftp.port
147
- end
148
- Util::FTPServer.start(Util::FTPLocalFS.new(location))
149
- end
159
+ # FTP server
160
+ setup_ftp_server(myftp) if myftp = option[:myftp]
150
161
 
151
- @tuple_space_server = TupleSpaceServer.new(
152
- task_worker_resource: option[:request_task_worker]
153
- )
162
+ # run tuple space server
163
+ @tuple_space_server = TupleSpaceServer.new(task_worker_resource: option[:request_task_worker])
164
+ set_tuple_space_server(@tuple_space_server)
154
165
 
155
- # setup base uri
166
+ # setup output location
156
167
  case option[:output_location]
157
168
  when Location::LocalLocation
158
169
  option[:output_location] = Location[option[:output_location].path.expand_path]
159
170
  option[:output_location].path.mkpath
160
171
  when Location::DropboxLocation
161
- # start session
162
- session = nil
163
- consumer_key = nil
164
- consumer_secret = nil
165
-
166
- cache = Pathname.new("~/.pione/dropbox_api.cache").expand_path
167
- if cache.exist?
168
- session = DropboxSession.deserialize(cache.read)
169
- Location::Dropbox.set_session(session)
170
- consumer_key = session.instance_variable_get(:@consumer_key)
171
- consumer_secret = session.instance_variable_get(:@consumer_secret)
172
- else
173
- api = YAML.load(Pathname.new("~/.pione/dropbox_api.yml").expand_path.read)
174
- consumer_key = api["key"]
175
- consumer_secret = api["secret"]
176
- session = DropboxSession.new(consumer_key, consumer_secret)
177
- Location::Dropbox.set_session(session)
178
- authorize_url = session.get_authorize_url
179
- puts "AUTHORIZING", authorize_url
180
- puts "Please visit that web page and hit 'Allow', then hit Enter here."
181
- STDIN.gets
182
- session.get_access_token
183
-
184
- # cache session
185
- cache.open("w+") {|c| c.write session.serialize}
186
- end
187
-
188
- # check session state
189
- unless session.authorized?
190
- abort("We cannot authorize dropbox access to PIONE.")
191
- end
192
-
193
- # share access token in tuple space
194
- Location::Dropbox.share_access_token(tuple_space_server, consumer_key, consumer_secret)
172
+ setup_dropbox
195
173
  end
196
174
 
197
175
  @tuple_space_server.set_base_location(option[:output_location])
198
176
  end
199
177
 
200
- start do
201
- read_process_document
178
+ start(:pre) {read_package}
202
179
 
180
+ # Print list of user parameters.
181
+ start do
203
182
  if option[:list_params]
204
- print_parameter_list
205
- exit!
206
- end
207
-
208
- write_tuples
209
- connect_relay if option[:relay]
210
- start_agents
183
+ unless @package.params.empty?
184
+ # print basic parameters
185
+ basic_user_params = @package.params.basic
186
+ unless basic_user_params.empty?
187
+ puts "Basic Paramters:"
188
+ basic_user_params.data.each do |var, val|
189
+ puts " %s := %s" % [var.name, val.textize]
190
+ end
191
+ end
211
192
 
212
- # start tuple space provider with thread
213
- # the thread is terminated when the client terminated
214
- unless option[:without_tuple_space_provider]
215
- @start_tuple_space_provider_thread = Thread.new do
216
- start_tuple_space_provider
193
+ advanced_user_params = @package.params.advanced
194
+ unless advanced_user_params.empty?
195
+ puts "Advanced Paramters:"
196
+ advanced_user_params.data.each do |var, val|
197
+ puts " %s := %s" % [var.name, val.textize]
198
+ end
199
+ end
200
+ else
201
+ puts " there are no user parameters in %s" % ARGF.path
217
202
  end
203
+ exit
218
204
  end
205
+ end
219
206
 
220
- start_workers
221
- @agent = Agent[:process_manager].start(@tuple_space_server, @document, option[:params], option[:stream])
222
- @agent.running_thread.join
207
+ # Run processing.
208
+ start do
209
+ # write tuples
210
+ write(Tuple[:process_info].new('standalone', 'Standalone'))
211
+ write(Tuple[:dry_run].new(option[:dry_run]))
212
+
213
+ # start
214
+ start_relay_connection if option[:relay]
215
+ start_precedent_agents
216
+ start_task_workers
217
+ start_process_manager
218
+
219
+ # check result
220
+ check_rehearsal_result if option[:rehearse]
221
+
222
+ @child_process_infos.each {|info| info.kill}
223
+ @child_process_infos.each {|info| info.wait}
223
224
  end
224
225
 
225
226
  terminate do
@@ -245,59 +246,88 @@ module Pione
245
246
 
246
247
  private
247
248
 
248
- # Read PIONE process document.
249
- #
250
- # @return [void]
251
- def read_process_document
252
- # process definition document is not found.
253
- if ARGF.filename == "-"
254
- abort("There are no process definition documents.")
249
+ # Setup FTP server with the URI.
250
+ def setup_ftp_server(uri)
251
+ location = Location[uri.path]
252
+ location.path.mkdir unless location.exist?
253
+ if uri.userinfo
254
+ Util::FTPServer.auth_info = Util::FTPAuthInfo.new(uri.user, uri.password)
255
255
  end
256
+ if uri.port
257
+ Util::FTPServer.port = myftp.port
258
+ end
259
+ Util::FTPServer.start(Util::FTPLocalFS.new(location))
260
+ end
256
261
 
257
- # get script dirname
258
- @dir = File.dirname(File.expand_path(__FILE__))
259
-
260
- location = Location[ARGF.path]
261
-
262
- # read process document
263
- begin
264
- if location.directory?
265
- # package
266
- package = Component::PackageReader.new(location).read
267
- package.upload(option[:output_location] + "package")
268
- if option[:rehearse]
269
- unless package.scenarios.empty?
270
- if scenario = package.find_scenario(option[:rehearse])
271
- option[:input_location] = scenario.input
272
- else
273
- abort "the scenario not found: %s" % option[:rehearse]
274
- end
275
- end
276
- end
277
- @document = package
278
- else
279
- @document = Component::Document.parse(location.read)
280
- end
281
- rescue Pione::Parser::ParserError => e
282
- abort("Pione syntax error: " + e.message)
283
- rescue Pione::Model::PioneModelTypeError, Pione::Model::VariableBindingError => e
284
- abort("Pione model error: " + e.message)
262
+ # Setup dropbox.
263
+ def setup_dropbox
264
+ # start session
265
+ session = nil
266
+ consumer_key = nil
267
+ consumer_secret = nil
268
+
269
+ cache = Pathname.new("~/.pione/dropbox_api.cache").expand_path
270
+ if cache.exist?
271
+ session = DropboxSession.deserialize(cache.read)
272
+ Location::Dropbox.set_session(session)
273
+ consumer_key = session.instance_variable_get(:@consumer_key)
274
+ consumer_secret = session.instance_variable_get(:@consumer_secret)
275
+ else
276
+ api = YAML.load(Pathname.new("~/.pione/dropbox_api.yml").expand_path.read)
277
+ consumer_key = api["key"]
278
+ consumer_secret = api["secret"]
279
+ session = DropboxSession.new(consumer_key, consumer_secret)
280
+ Location::Dropbox.set_session(session)
281
+ authorize_url = session.get_authorize_url
282
+ puts "AUTHORIZING", authorize_url
283
+ puts "Please visit that web page and hit 'Allow', then hit Enter here."
284
+ STDIN.gets
285
+ session.get_access_token
286
+
287
+ # cache session
288
+ cache.open("w+") {|c| c.write session.serialize}
289
+ end
290
+
291
+ # check session state
292
+ unless session.authorized?
293
+ abort("We cannot authorize dropbox access to PIONE.")
285
294
  end
295
+
296
+ # share access token in tuple space
297
+ Location::Dropbox.share_access_token(tuple_space_server, consumer_key, consumer_secret)
286
298
  end
287
299
 
288
- # Write initial tuples.
300
+ # Read a package.
289
301
  #
290
302
  # @return [void]
291
- def write_tuples
292
- [ Tuple[:process_info].new('standalone', 'Standalone'),
293
- Tuple[:dry_run].new(option[:dry_run])
294
- ].each {|tuple| @tuple_space_server.write(tuple) }
303
+ def read_package
304
+ # package is not found
305
+ if @argv.first.nil?
306
+ abort("There are no PIONE documents or packages.")
307
+ end
308
+
309
+ # read package
310
+ @package = Component::PackageReader.read(Location[@argv.first])
311
+ @package.upload(option[:output_location] + "package")
312
+
313
+ # check rehearse scenario
314
+ if option[:rehearse] and not(@package.scenarios.empty?)
315
+ if scenario = @package.find_scenario(option[:rehearse])
316
+ option[:input_location] = scenario.input
317
+ else
318
+ abort "the scenario not found: %s" % option[:rehearse]
319
+ end
320
+ end
321
+ rescue Pione::Parser::ParserError => e
322
+ abort("Pione syntax error: " + e.message)
323
+ rescue Pione::Model::PioneModelTypeError, Pione::Model::VariableBindingError => e
324
+ abort("Pione model error: " + e.message)
295
325
  end
296
326
 
297
327
  # Start agent activities.
298
328
  #
299
329
  # @return [void]
300
- def start_agents
330
+ def start_precedent_agents
301
331
  # messenger
302
332
  @messenger = Agent[:messenger].start(@tuple_space_server)
303
333
 
@@ -306,7 +336,7 @@ module Pione
306
336
 
307
337
  # rule provider
308
338
  @rule_loader = Agent[:rule_provider].start(@tuple_space_server)
309
- @rule_loader.read_document(@document)
339
+ @rule_loader.read_rules(@package)
310
340
  @rule_loader.wait_till(:request_waiting)
311
341
 
312
342
  # input generators
@@ -317,30 +347,42 @@ module Pione
317
347
 
318
348
  # command listener
319
349
  @command_listener = Agent[:command_listener].start(@tuple_space_server, self)
320
- end
321
350
 
322
- # Wake up tuple space provider process and connect my tuple space server
323
- # to it.
324
- def start_tuple_space_provider
325
- @tuple_space_provider = Pione::TupleSpaceProvider.instance
326
- @tuple_space_provider.add_tuple_space_server(@tuple_space_server)
351
+ # start tuple space provider and connect tuple space server
352
+ unless option[:without_tuple_space_provider]
353
+ @start_tuple_space_provider_thread = Thread.new do
354
+ @tuple_space_provider = Pione::TupleSpaceProvider.instance(@child_process_infos)
355
+ @tuple_space_provider.add_tuple_space_server(@tuple_space_server)
356
+ end
357
+ end
327
358
  end
328
359
 
329
360
  # Start task workers.
330
- #
331
- # @return [void]
332
- def start_workers
361
+ def start_task_workers
362
+ features = DocumentTransformer.new.apply(
363
+ DocumentParser.new.feature_expr.parse(option[:features])
364
+ )
333
365
  option[:task_worker].times do
334
- Thread.new {
335
- Agent[:task_worker].spawn(Global.front, Util::UUID.generate, option[:features])
336
- }
366
+ if option[:stand_alone]
367
+ Thread.new do
368
+ Agent[:task_worker].start(@tuple_space_server, features)
369
+ end
370
+ else
371
+ Thread.new do
372
+ @child_process_infos << Agent[:task_worker].spawn(Global.front, Util::UUID.generate, option[:features])
373
+ end
374
+ end
337
375
  end
338
376
  end
339
377
 
378
+ # Start process manager agent.
379
+ def start_process_manager
380
+ @agent = Agent[:process_manager].start(@tuple_space_server, @package, option[:params], option[:stream])
381
+ @agent.running_thread.join
382
+ end
383
+
340
384
  # Connect relay server.
341
- #
342
- # @return [void]
343
- def connect_relay
385
+ def start_relay_connection
344
386
  Global.relay_tuple_space_server = @tuple_space_server
345
387
  @relay_ref = DRbObject.new_with_uri(option[:relay])
346
388
  @relay_ref.__connect
@@ -361,13 +403,18 @@ module Pione
361
403
  abort("You failed authentication to connect the relay server: %s" % @relay_ref.__drburi)
362
404
  end
363
405
 
364
- # Print parameter list of the document.
365
- #
366
- # @return [void]
367
- def print_parameter_list
368
- puts "Parameters:"
369
- @document.params.data.select{|var, val| var.user_param}.each do |var, val|
370
- puts " %s := %s" % [var.name, val.textize]
406
+ # Check rehearsal result.
407
+ def check_rehearsal_result
408
+ return unless option[:rehearse] and not(@package.scenarios.empty?)
409
+ return unless scenario = @package.find_scenario(option[:rehearse])
410
+
411
+ errors = scenario.validate(option[:output_location])
412
+ if errors.empty?
413
+ puts "Rehearsal Result: Succeeded"
414
+ else
415
+ puts "Rehearsal Result: Failed"
416
+ errors.each {|error| puts "- %s" % error.to_s}
417
+ Global.exit_status = false
371
418
  end
372
419
  end
373
420
  end