pione 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +1 -0
  3. data/History.txt +7 -0
  4. data/example/DeferredChoice/DeferredChoice.pione +14 -7
  5. data/{misc → example/DeferredChoice/bin}/ui.xml +11 -6
  6. data/example/DeferredChoice/pione-package.json +1 -1
  7. data/example/DeferredChoiceWithPage/DeferredChoiceWithPage.pione +47 -0
  8. data/example/DeferredChoiceWithPage/etc/index.html +22 -0
  9. data/example/DeferredChoiceWithPage/pione-package.json +18 -0
  10. data/example/Interaction/Interaction.pione +27 -0
  11. data/example/Interaction/bin/show-environment.cgi +45 -0
  12. data/example/Interaction/etc/.hidden-file.txt +1 -0
  13. data/example/Interaction/etc/cgi.html +46 -0
  14. data/example/Interaction/etc/create-files.html +51 -0
  15. data/example/Interaction/etc/delete-files.html +31 -0
  16. data/example/Interaction/etc/get-files.html +21 -0
  17. data/example/Interaction/etc/index.html +18 -0
  18. data/example/Interaction/etc/list-files.html +36 -0
  19. data/example/Interaction/pione-package.json +24 -0
  20. data/lib/pione/agent/job-manager.rb +19 -3
  21. data/lib/pione/agent/logger.rb +9 -9
  22. data/lib/pione/agent/messenger.rb +3 -2
  23. data/lib/pione/agent/task-worker.rb +32 -10
  24. data/lib/pione/command/option.rb +18 -0
  25. data/lib/pione/command/pione-client.rb +51 -22
  26. data/lib/pione/command/pione-interactive.rb +128 -55
  27. data/lib/pione/command/pione-package-build.rb +3 -3
  28. data/lib/pione/command/pione-task-worker.rb +23 -10
  29. data/lib/pione/command/pione-tuple-space-provider.rb +8 -8
  30. data/lib/pione/command/spawner.rb +28 -1
  31. data/lib/pione/front/interactive-front.rb +76 -0
  32. data/lib/pione/global/interactive-variable.rb +26 -0
  33. data/lib/pione/log/message-log-receiver.rb +4 -2
  34. data/lib/pione/model/task-worker-broker-model.rb +7 -1
  35. data/lib/pione/package/package-archiver.rb +16 -9
  36. data/lib/pione/package/package-handler.rb +6 -0
  37. data/lib/pione/package/package-info.rb +4 -0
  38. data/lib/pione/package/package-reader.rb +2 -4
  39. data/lib/pione/package/package-scanner.rb +23 -3
  40. data/lib/pione/rule-engine.rb +48 -19
  41. data/lib/pione/rule-engine/action-handler.rb +29 -5
  42. data/lib/pione/rule-engine/basic-handler.rb +27 -19
  43. data/lib/pione/test-helper/command-helper.rb +1 -1
  44. data/lib/pione/tuple-space/tuple-definition.yml +2 -3
  45. data/lib/pione/tuple-space/tuple-space-server.rb +8 -0
  46. data/lib/pione/util/cgi.rb +326 -0
  47. data/lib/pione/version.rb +1 -1
  48. data/lib/rootage/normalizer.rb +4 -0
  49. data/lib/rootage/option.rb +11 -4
  50. data/test/agent/spec_logger.rb +0 -1
  51. data/test/agent/spec_messenger.rb +1 -1
  52. data/test/command/spec_pione-client.rb +4 -4
  53. data/test/log/spec_message-log.rb +1 -1
  54. data/test/rule-engine/spec_action-handler.rb +25 -5
  55. data/test/rule-engine/spec_empty-handler.rb +36 -3
  56. data/test/rule-engine/spec_flow-handler.rb +90 -7
  57. metadata +22 -72
  58. data/misc/test-drb-stop-service.rb +0 -34
  59. data/misc/test-many-waiters-client.rb +0 -56
  60. data/misc/test-many-waiters-server.rb +0 -14
@@ -89,12 +89,12 @@ module Pione
89
89
  item.process do
90
90
  model[:source_locations].each do |location|
91
91
  if ppg = try_to_archive(location)
92
- Log::SystemLog.info("Package build suceeded: %s" % ppg.address)
92
+ Log::SystemLog.info("Package build process has succeeded: %s" % ppg.address)
93
93
  cmd.terminate
94
94
  end
95
95
  end
96
96
 
97
- cmd.abort("Package build has failed to archive.")
97
+ cmd.abort("Package build process has failed.")
98
98
  end
99
99
  end
100
100
  end
@@ -111,7 +111,7 @@ module Pione
111
111
  # archive
112
112
  return archiver.archive(model[:output], false)
113
113
  rescue => e
114
- Log::Debug.system("PIONE failed to archive %s: %s" % [location, e.message])
114
+ Log::Debug.system("PIONE has failed to archive %s: %s" % [location, e.message])
115
115
  end
116
116
  end
117
117
 
@@ -7,24 +7,31 @@ module Pione
7
7
  #
8
8
 
9
9
  # Create a new process of `pione-task-worker` command.
10
- def self.spawn(model, features, tuple_space_id)
10
+ #
11
+ # @param [Rootage::Model] model
12
+ # @param [Hash] param
13
+ # @option param [Array<String>] :features
14
+ # list of features that the task worker has
15
+ # @option param [String] :tuple_space_id
16
+ # ID of tuple space that the task worker works in
17
+ def self.spawn(model, param={})
11
18
  spawner = Spawner.new(model, "pione-task-worker")
12
19
 
13
20
  # debug options
14
- spawner.option("--debug=system") if Global.debug_system
15
- spawner.option("--debug=ignored_exception") if Global.debug_ignored_exception
16
- spawner.option("--debug=rule_engine") if Global.debug_rule_engine
17
- spawner.option("--debug=communication") if Global.debug_communication
18
- spawner.option("--debug=notification") if Global.debug_notification
21
+ spawner.option_if(Global.debug_system, "--debug=system")
22
+ spawner.option_if(Global.debug_ignored_exception, "--debug=ignored_exception")
23
+ spawner.option_if(Global.debug_rule_engine, "--debug=rule_engine")
24
+ spawner.option_if(Global.debug_communication, "--debug=communication")
25
+ spawner.option_if(Global.debug_notification, "--debug=notification")
19
26
 
20
27
  # requisite options
21
- spawner.option("--parent-front", model[:front].uri.to_s)
22
- spawner.option("--tuple-space-id", tuple_space_id)
23
- spawner.option("--features", features) if features
28
+ spawner.option_from(model, :front, "--parent-front", lambda {|val| val.uri})
29
+ spawner.option_from(param, :tuple_space_id, "--tuple-space-id")
30
+ spawner.option_from(param, :features, "--features")
24
31
 
25
32
  # others
26
33
  spawner.option("--color", Global.color_enabled)
27
- spawner.option("--file-cache-method", System::FileCache.cache_method.name.to_s)
34
+ spawner.option("--file-cache-method", System::FileCache.cache_method.name)
28
35
  spawner.option("--file-sliding", Global.file_sliding)
29
36
 
30
37
  spawner.spawn # this method returns child front
@@ -51,6 +58,9 @@ module Pione
51
58
  option CommonOption.file_cache_method
52
59
  option CommonOption.file_sliding
53
60
 
61
+ option(SessionOption.request_from)
62
+ option(SessionOption.session_id)
63
+
54
64
  option(:tuple_space_id) do |item|
55
65
  item.type = :string
56
66
  item.long = '--tuple-space-id'
@@ -99,6 +109,9 @@ module Pione
99
109
  cmd.abort('"%{name}" cannot connect to tuple space.' % {name: cmd.name})
100
110
  end
101
111
  end
112
+
113
+ item.assign(:request_from) {model[:tuple_space].attribute("request_from")}
114
+ item.assign(:session_id) {model[:tuple_space].attribute("session_id")}
102
115
  end
103
116
 
104
117
  setup(:task_worker_agent) do |item|
@@ -11,17 +11,17 @@ module Pione
11
11
  spawner = Spawner.new(cmd.model, "pione-tuple-space-provider")
12
12
 
13
13
  # debug options
14
- spawner.option("--debug=system") if Global.debug_system
15
- spawner.option("--debug=ignored_exception") if Global.debug_ignored_exception
16
- spawner.option("--debug=rule_engine") if Global.debug_rule_engine
17
- spawner.option("--debug=communication") if Global.debug_communication
18
- spawner.option("--debug=notification") if Global.debug_notification
14
+ spawner.option_if(Global.debug_system, "--debug=system")
15
+ spawner.option_if(Global.debug_ignored_exception, "--debug=ignored_exception")
16
+ spawner.option_if(Global.debug_rule_engine, "--debug=rule_engine")
17
+ spawner.option_if(Global.debug_communication, "--debug=communication")
18
+ spawner.option_if(Global.debug_notification, "--debug=notification")
19
19
 
20
20
  # requisite options
21
- spawner.option("--parent-front", cmd.model[:front].uri.to_s)
22
- spawner.option("--communication-address", Global.communication_address.to_s)
21
+ spawner.option("--parent-front", cmd.model[:front].uri)
22
+ spawner.option("--communication-address", Global.communication_address)
23
23
  Global.notification_targets.each do |address|
24
- spawner.option("--notification-target", address.to_s)
24
+ spawner.option("--notification-target", address)
25
25
  end
26
26
 
27
27
  # optionals
@@ -49,11 +49,38 @@ module Pione
49
49
  end
50
50
  end
51
51
 
52
- # Append arguments to the command.
52
+ # Add arguments as command arguments.
53
53
  def option(*argv)
54
54
  @argv += argv.map {|val| val.to_s}
55
55
  end
56
56
 
57
+ # Add arguments if the condition is true.
58
+ def option_if(cond, *args)
59
+ if cond
60
+ option(*args)
61
+ end
62
+ end
63
+
64
+ # Add the option name and the value as command arguments. If the value
65
+ # doesn't exist in the table or the value is `nil`, no options are
66
+ # added. This is useful for the case a caller's command option passes
67
+ # callee's.
68
+ #
69
+ # @param [Hash] table
70
+ # value table
71
+ # @param [Symbol] key
72
+ # key of the value table
73
+ # @param [String] option_name
74
+ # option name
75
+ # @return [void]
76
+ def option_from(table, key, option_name, converter=nil)
77
+ if table[key]
78
+ val = table[key]
79
+ val = converter.call(val) if converter
80
+ option(option_name, val)
81
+ end
82
+ end
83
+
57
84
  # Register the block that is executed when the spawned process is terminated.
58
85
  def when_terminated(&b)
59
86
  Thread.new do
@@ -0,0 +1,76 @@
1
+ module Pione
2
+ module Front
3
+ # InteractiveFront is a front interface for +pione-interactive+ command.
4
+ class InteractiveFront < BasicFront
5
+ def initialize(cmd)
6
+ super(cmd, Global.interactive_front_port_range)
7
+ end
8
+
9
+ # Read data string from the path. This path should be relative from public
10
+ # directory of pione-interactive.
11
+ #
12
+ # @param [String] path
13
+ # relative path from public directory
14
+ # @param [Hash] params
15
+ # parameters to pass to the CGI program
16
+ def get(path, cgi_info)
17
+ local_file = (@cmd.model[:public] + path)
18
+ if local_file.path.executable?
19
+ return Util::CGIExecutor.new(local_file.path, cgi_info, @cmd.model[:public], @cmd.model[:timeout]).exec
20
+ else
21
+ begin
22
+ local_file.read
23
+ rescue
24
+ return nil
25
+ end
26
+ end
27
+ end
28
+
29
+ # Create a file with the content. Thie operation returns true only if the
30
+ # file creation has succeeded.
31
+ def create(path, content)
32
+ begin
33
+ (@cmd.model[:public] + path).write(content)
34
+ return true
35
+ rescue => e
36
+ return false
37
+ end
38
+ end
39
+
40
+ # Delete the file. Thie operation returns true only if the file deletion
41
+ # has succeeded.
42
+ def delete(path)
43
+ begin
44
+ (@cmd.model[:public] + path).delete
45
+ return true
46
+ rescue => e
47
+ return false
48
+ end
49
+ end
50
+
51
+ # Return entry informations in the directory. When the operation returns
52
+ # nil, the file listing has failed. When this returns false, the path is
53
+ # file.
54
+ def list(path, show_all)
55
+ begin
56
+ unless (@cmd.model[:public] + path).directory?
57
+ return false
58
+ end
59
+
60
+ (@cmd.model[:public] + path).entries.each_with_object([]) do |entry, list|
61
+ if show_all or not(entry.basename.start_with?("."))
62
+ list << {
63
+ "name" => entry.basename,
64
+ "type" => entry.directory? ? "dir" : "file",
65
+ "mtime" => entry.mtime.iso8601,
66
+ "size" => entry.size
67
+ }
68
+ end
69
+ end
70
+ rescue => e
71
+ return nil
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,26 @@
1
+ module Pione
2
+ module Global
3
+ # This is a begin number of port range for pione-interactive's front.
4
+ define_external_item(:interactive_front_port_range_begin) do |item|
5
+ item.desc = "start port number of interactive front"
6
+ item.init = 40900
7
+ end
8
+
9
+ # This is an end number of port range for pione-interactive's front.
10
+ define_external_item(:interactive_front_port_range_end) do |item|
11
+ item.desc = "end port number of interactive front"
12
+ item.init = 40999
13
+ end
14
+
15
+ # This is port range for pione-interactive's front.
16
+ define_computed_item(:interactive_front_port_range, [:interactive_front_port_range_begin, :interactive_front_port_range_end]) do |item|
17
+ item.desc = "port range of interactive front"
18
+ item.define_updater do
19
+ Range.new(
20
+ Global.interactive_front_port_range_begin,
21
+ Global.interactive_front_port_range_end
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -12,7 +12,9 @@ module Pione
12
12
  # message header
13
13
  # @param color [String]
14
14
  # message color
15
- def receiver(message, level, header, color)
15
+ # @param session_id [String]
16
+ # session_id
17
+ def receiver(message, level, header, color, session_id)
16
18
  raise NotImplementedError.new
17
19
  end
18
20
  end
@@ -24,7 +26,7 @@ module Pione
24
26
  @out = out
25
27
  end
26
28
 
27
- def receive(message, level, header, color)
29
+ def receive(message, level, header, color, session_id)
28
30
  @out.puts "%s%s %s" % [" "*level, ("%5s" % header).color(color), message]
29
31
  end
30
32
  end
@@ -35,8 +35,14 @@ module Pione
35
35
 
36
36
  # spawn a new process of pione-task-worker command
37
37
  if self[:spawn_task_worker]
38
+ # make task worker's parameters
39
+ param = {
40
+ :features => Global.features,
41
+ :tuple_space_id => tuple_space.uuid
42
+ }
43
+
38
44
  begin
39
- spawner = Command::PioneTaskWorker.spawn(self, Global.features, tuple_space.uuid)
45
+ spawner = Command::PioneTaskWorker.spawn(self, param)
40
46
  @task_workers << spawner.child_front
41
47
  spawner.when_terminated {delete_task_worker(spawner.child_front)}
42
48
  rescue Command::SpawnError => e
@@ -31,6 +31,7 @@ module Pione
31
31
  archive_documents(zip, info)
32
32
  archive_scenarios(zip)
33
33
  archive_bins(zip, info)
34
+ archive_etcs(zip, info)
34
35
  archive_digest(zip, digest)
35
36
  end
36
37
 
@@ -57,13 +58,13 @@ module Pione
57
58
 
58
59
  # Archive package info file.
59
60
  def archive_package_info(zip)
60
- add_file_with_keeping_time(zip, "pione-package.json", @location + "pione-package.json")
61
+ add_file_with_time(zip, "pione-package.json", @location + "pione-package.json")
61
62
  end
62
63
 
63
64
  # Archive documents based on package info file.
64
65
  def archive_documents(zip, info)
65
66
  info.documents.each do |document|
66
- add_file_with_keeping_time(zip, document, @location + document)
67
+ add_file_with_time(zip, document, @location + document)
67
68
  end
68
69
  end
69
70
 
@@ -87,13 +88,13 @@ module Pione
87
88
  # Archive scenario document file.
88
89
  def archive_scenario_document(zip, scenario)
89
90
  document_location = @location + scenario + "Scenario.pione"
90
- add_file_with_keeping_time(zip, File.join(scenario, "Scenario.pione"), document_location)
91
+ add_file_with_time(zip, File.join(scenario, "Scenario.pione"), document_location)
91
92
  end
92
93
 
93
94
  # Archive scenario info file.
94
95
  def archive_scenario_info(zip, scenario)
95
96
  info_location = @location + scenario + "pione-scenario.json"
96
- add_file_with_keeping_time(zip, File.join(scenario, "pione-scenario.json"), info_location)
97
+ add_file_with_time(zip, File.join(scenario, "pione-scenario.json"), info_location)
97
98
  end
98
99
 
99
100
  # Archive input data of the scenario.
@@ -105,7 +106,7 @@ module Pione
105
106
  # archive input data
106
107
  info.inputs.each do |input|
107
108
  input_location = @location + scenario + input
108
- add_file_with_keeping_time(zip, File.join(scenario, input), input_location)
109
+ add_file_with_time(zip, File.join(scenario, input), input_location)
109
110
  end
110
111
  end
111
112
  end
@@ -118,21 +119,27 @@ module Pione
118
119
 
119
120
  info.outputs.each do |output|
120
121
  output_location = @location + scenario + output
121
- add_file_with_keeping_time(zip, File.join(scenario, output), output_location)
122
+ add_file_with_time(zip, File.join(scenario, output), output_location)
122
123
  end
123
124
  end
124
125
  end
125
126
 
126
127
  def archive_bins(zip, info)
127
128
  info.bins.each do |bin|
128
- add_file_with_keeping_time(zip, bin, @location + bin)
129
+ add_file_with_time(zip, bin, @location + bin)
130
+ end
131
+ end
132
+
133
+ def archive_etcs(zip, info)
134
+ info.etcs.each do |file|
135
+ add_file_with_time(zip, file, @location + file)
129
136
  end
130
137
  end
131
138
 
132
139
  def archive_digest(zip, digest)
133
140
  digest_location = Location[Temppath.create]
134
141
  digest_location.write(digest)
135
- add_file_with_keeping_time(zip, ".digest", digest_location)
142
+ add_file_with_time(zip, ".digest", digest_location)
136
143
  end
137
144
 
138
145
  def mkdir_with_time(zip, path, time)
@@ -142,7 +149,7 @@ module Pione
142
149
  entry.extra.delete("UniversalTime")
143
150
  end
144
151
 
145
- def add_file_with_keeping_time(zip, path, orig_location)
152
+ def add_file_with_time(zip, path, orig_location)
146
153
  entry = zip.add(path, orig_location.path.to_s)
147
154
  entry.time = Zip::DOSTime.at(orig_location.mtime)
148
155
  entry.extra.delete("UniversalTime")
@@ -69,9 +69,15 @@ module Pione
69
69
 
70
70
  # Upload the package files to the location.
71
71
  def upload(dest)
72
+ # upload bins
72
73
  @info.bins.each do |entry|
73
74
  (@location + entry).copy(dest + entry)
74
75
  end
76
+
77
+ # upload etc files
78
+ @info.etcs.each do |entry|
79
+ (@location + entry).copy(dest + entry)
80
+ end
75
81
  end
76
82
 
77
83
  # Find scenario that have the name.
@@ -9,6 +9,7 @@ module Pione
9
9
  member :documents, default: lambda { Array.new }
10
10
  member :scenarios, default: lambda { Array.new }
11
11
  member :bins, default: lambda { Array.new }
12
+ member :etcs, default: lambda { Array.new }
12
13
 
13
14
  # Read package information from the string.
14
15
  def self.read(str)
@@ -21,6 +22,7 @@ module Pione
21
22
  args[:documents] = data["Documents"]
22
23
  args[:scenarios] = data["Scenarios"]
23
24
  args[:bins] = data["Bins"]
25
+ args[:etcs] = data["Etcs"]
24
26
  new(args)
25
27
  end
26
28
 
@@ -29,6 +31,7 @@ module Pione
29
31
  list = []
30
32
  list += documents
31
33
  list += bins
34
+ list += etcs
32
35
  return list
33
36
  end
34
37
 
@@ -42,6 +45,7 @@ module Pione
42
45
  data["Documents"] = documents
43
46
  data["Scenarios"] = scenarios
44
47
  data["Bins"] = bins
48
+ data["Etcs"] = etcs
45
49
  data.to_json(*args)
46
50
  end
47
51
  end
@@ -114,14 +114,12 @@ module Pione
114
114
  # make temporary directory
115
115
  local_location = Location[Temppath.create]
116
116
 
117
- # copy files to local
118
-
119
117
  # pione-package.json
120
118
  info = PackageInfo.read((@location + "pione-package.json").read)
121
119
  (@location + "pione-package.json").copy(local_location + "pione-package.json")
122
120
 
123
- # documents
124
- (info.documents + info.bins).each do |path|
121
+ # copy files
122
+ (info.documents + info.bins + info.etcs).each do |path|
125
123
  (@location + path).copy(local_location + path)
126
124
  end
127
125
 
@@ -18,10 +18,17 @@ module Pione
18
18
  name, editor, tag, parents = scan_annotations(documents)
19
19
  scenarios = scan_scenarios(@package_location)
20
20
  bins = scan_bins(@package_location)
21
+ etcs = scan_etcs(@package_location)
21
22
 
22
23
  return PackageInfo.new(
23
- name: name, editor: editor, tag: tag, parents: parents,
24
- documents: documents, scenarios: scenarios, bins: bins
24
+ name: name,
25
+ editor: editor,
26
+ tag: tag,
27
+ parents: parents,
28
+ documents: documents,
29
+ scenarios: scenarios,
30
+ bins: bins,
31
+ etcs: etcs
25
32
  )
26
33
  else
27
34
  # the case for single document package
@@ -116,7 +123,7 @@ module Pione
116
123
  end
117
124
  end
118
125
 
119
- # Scan script files.
126
+ # Scan executable files.
120
127
  def scan_bins(location)
121
128
  if (location + "bin").exist?
122
129
  (location + "bin").entries.each_with_object([]) do |entry, list|
@@ -128,6 +135,19 @@ module Pione
128
135
  return []
129
136
  end
130
137
  end
138
+
139
+ # Scan etc files.
140
+ def scan_etcs(location)
141
+ if (location + "etc").exist?
142
+ (location + "etc").entries.each_with_object([]) do |entry, list|
143
+ if entry.file?
144
+ list << entry.path.relative_path_from(@package_location.path).to_s
145
+ end
146
+ end
147
+ else
148
+ return []
149
+ end
150
+ end
131
151
  end
132
152
  end
133
153
  end