pione 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (304) hide show
  1. data/.gitignore +2 -0
  2. data/.s3cfg +42 -0
  3. data/.travis.yml +18 -4
  4. data/.yardopts +1 -0
  5. data/Gemfile +3 -0
  6. data/History.txt +14 -0
  7. data/Procfile +7 -0
  8. data/Rakefile +25 -0
  9. data/bin/pione-interactive +6 -0
  10. data/bin/{pione-compiler → pione-notification-listener} +1 -1
  11. data/bin/{pione-broker → pione-task-worker-broker} +1 -1
  12. data/doc/man/pione-list-param.md +36 -0
  13. data/example/ActionError/ActionError.pione +9 -0
  14. data/example/ActionError/pione-package.json +15 -0
  15. data/example/CountChar/CountChar.pione +1 -1
  16. data/example/ScoreAggregation/ScoreAggregation.pione +1 -1
  17. data/example/Touch/pione-package.json +15 -0
  18. data/lib/pione.rb +12 -0
  19. data/lib/pione/agent.rb +3 -3
  20. data/lib/pione/agent/basic-agent.rb +10 -4
  21. data/lib/pione/agent/input-generator.rb +3 -3
  22. data/lib/pione/agent/{process-manager.rb → job-manager.rb} +10 -7
  23. data/lib/pione/agent/job-terminator.rb +2 -2
  24. data/lib/pione/agent/logger.rb +3 -3
  25. data/lib/pione/agent/messenger.rb +20 -9
  26. data/lib/pione/agent/notification-listener.rb +88 -0
  27. data/lib/pione/agent/task-worker-broker.rb +84 -0
  28. data/lib/pione/agent/task-worker.rb +3 -2
  29. data/lib/pione/agent/tuple-space-client.rb +1 -0
  30. data/lib/pione/agent/tuple-space-provider.rb +17 -35
  31. data/lib/pione/command.rb +33 -15
  32. data/lib/pione/command/action.rb +105 -0
  33. data/lib/pione/command/basic-command.rb +34 -376
  34. data/lib/pione/command/command-exception.rb +12 -11
  35. data/lib/pione/command/common.rb +198 -0
  36. data/lib/pione/command/option.rb +159 -204
  37. data/lib/pione/command/pione-action-exec.rb +85 -0
  38. data/lib/pione/command/pione-action-list.rb +43 -19
  39. data/lib/pione/command/pione-action-print.rb +79 -0
  40. data/lib/pione/command/pione-action.rb +8 -67
  41. data/lib/pione/command/pione-clean.rb +88 -68
  42. data/lib/pione/command/pione-client.rb +475 -332
  43. data/lib/pione/command/pione-command.rb +14 -31
  44. data/lib/pione/command/pione-compile.rb +90 -0
  45. data/lib/pione/command/pione-config-get.rb +53 -0
  46. data/lib/pione/command/pione-config-list.rb +64 -0
  47. data/lib/pione/command/pione-config-set.rb +59 -0
  48. data/lib/pione/command/pione-config-unset.rb +50 -0
  49. data/lib/pione/command/pione-config.rb +61 -0
  50. data/lib/pione/command/pione-diagnosis-notification.rb +235 -0
  51. data/lib/pione/command/pione-diagnosis.rb +21 -0
  52. data/lib/pione/command/pione-interactive.rb +188 -0
  53. data/lib/pione/command/pione-lang-check-syntax.rb +163 -0
  54. data/lib/pione/command/pione-lang-interactive.rb +146 -0
  55. data/lib/pione/command/pione-lang.rb +22 -0
  56. data/lib/pione/command/pione-log-format.rb +163 -0
  57. data/lib/pione/command/pione-log-list-id.rb +48 -0
  58. data/lib/pione/command/pione-log.rb +19 -101
  59. data/lib/pione/command/pione-notification-listener.rb +95 -0
  60. data/lib/pione/command/pione-package-add.rb +137 -0
  61. data/lib/pione/command/pione-package-build.rb +122 -0
  62. data/lib/pione/command/pione-package-show.rb +96 -0
  63. data/lib/pione/command/pione-package-update.rb +59 -0
  64. data/lib/pione/command/pione-package.rb +11 -139
  65. data/lib/pione/command/pione-task-worker-broker.rb +88 -0
  66. data/lib/pione/command/pione-task-worker.rb +148 -98
  67. data/lib/pione/command/pione-tuple-space-provider.rb +62 -54
  68. data/lib/pione/command/pione-tuple-space-viewer.rb +105 -83
  69. data/lib/pione/command/pione-val.rb +39 -39
  70. data/lib/pione/command/spawner.rb +34 -27
  71. data/lib/pione/front.rb +4 -2
  72. data/lib/pione/front/basic-front.rb +86 -23
  73. data/lib/pione/front/client-front.rb +2 -2
  74. data/lib/pione/front/diagnosis-notification-front.rb +40 -0
  75. data/lib/pione/front/front-exception.rb +7 -1
  76. data/lib/pione/front/notification-listener-front.rb +36 -0
  77. data/lib/pione/front/notification-recipient-interface.rb +19 -0
  78. data/lib/pione/front/relay-front.rb +4 -4
  79. data/lib/pione/front/task-worker-broker-front.rb +19 -0
  80. data/lib/pione/front/task-worker-front.rb +2 -2
  81. data/lib/pione/front/tuple-space-provider-front.rb +3 -2
  82. data/lib/pione/global.rb +3 -1
  83. data/lib/pione/global/client-variable.rb +1 -1
  84. data/lib/pione/global/config.rb +63 -7
  85. data/lib/pione/global/diagnosis-variable.rb +26 -0
  86. data/lib/pione/global/item.rb +28 -5
  87. data/lib/pione/global/log-variable.rb +6 -5
  88. data/lib/pione/global/network-variable.rb +75 -4
  89. data/lib/pione/global/path-variable.rb +1 -1
  90. data/lib/pione/global/system-variable.rb +12 -12
  91. data/lib/pione/global/task-worker-broker-variable.rb +43 -0
  92. data/lib/pione/global/tuple-space-notifier-variable.rb +3 -55
  93. data/lib/pione/lang/boolean.rb +4 -0
  94. data/lib/pione/lang/data-expr.rb +1 -1
  95. data/lib/pione/lang/integer.rb +1 -1
  96. data/lib/pione/lang/string.rb +4 -0
  97. data/lib/pione/lang/type.rb +1 -1
  98. data/lib/pione/location.rb +1 -0
  99. data/lib/pione/location/data-location.rb +41 -13
  100. data/lib/pione/location/dropbox-location.rb +175 -56
  101. data/lib/pione/location/ftp-location.rb +4 -1
  102. data/lib/pione/location/http-location.rb +5 -3
  103. data/lib/pione/location/https-location.rb +4 -2
  104. data/lib/pione/location/local-location.rb +6 -3
  105. data/lib/pione/location/location-exception.rb +12 -0
  106. data/lib/pione/location/notification-scheme.rb +46 -0
  107. data/lib/pione/log.rb +8 -7
  108. data/lib/pione/log/debug.rb +9 -9
  109. data/lib/pione/log/domain-log.rb +6 -1
  110. data/lib/pione/log/message-log-receiver.rb +32 -0
  111. data/lib/pione/log/system-log.rb +62 -141
  112. data/lib/pione/model.rb +7 -0
  113. data/lib/pione/model/notification-listener-model.rb +29 -0
  114. data/lib/pione/model/task-worker-broker-model.rb +129 -0
  115. data/lib/pione/notification.rb +13 -0
  116. data/lib/pione/notification/address.rb +104 -0
  117. data/lib/pione/notification/exception.rb +10 -0
  118. data/lib/pione/notification/message.rb +109 -0
  119. data/lib/pione/notification/receiver.rb +90 -0
  120. data/lib/pione/notification/recipient.rb +68 -0
  121. data/lib/pione/notification/task-worker-broker-recipient.rb +85 -0
  122. data/lib/pione/notification/transmitter.rb +84 -0
  123. data/lib/pione/pnml.rb +35 -0
  124. data/lib/pione/pnml/annotation-extractor.rb +47 -0
  125. data/lib/pione/pnml/compiler.rb +176 -0
  126. data/lib/pione/pnml/input-merge-complement.rb +78 -0
  127. data/lib/pione/pnml/input-parallelization-complement.rb +75 -0
  128. data/lib/pione/pnml/input-reduction.rb +80 -0
  129. data/lib/pione/pnml/invalid-arc-elimination.rb +41 -0
  130. data/lib/pione/pnml/io-expansion.rb +88 -0
  131. data/lib/pione/pnml/isolated-element-elimination.rb +32 -0
  132. data/lib/pione/pnml/net-rewriter.rb +44 -0
  133. data/lib/pione/pnml/output-decomposition-complement.rb +77 -0
  134. data/lib/pione/pnml/output-reduction.rb +86 -0
  135. data/lib/pione/pnml/output-synchronization-complement.rb +77 -0
  136. data/lib/pione/pnml/pione-model.rb +417 -0
  137. data/lib/pione/pnml/pnml-exception.rb +23 -0
  138. data/lib/pione/pnml/pnml-model.rb +368 -0
  139. data/lib/pione/pnml/reader.rb +51 -0
  140. data/lib/pione/rule-engine/action-handler.rb +8 -6
  141. data/lib/pione/rule-engine/basic-handler.rb +5 -5
  142. data/lib/pione/rule-engine/engine-exception.rb +7 -6
  143. data/lib/pione/rule-engine/flow-handler.rb +27 -18
  144. data/lib/pione/system.rb +3 -1
  145. data/lib/pione/system/domain-dump.rb +34 -0
  146. data/lib/pione/system/file-cache.rb +92 -13
  147. data/lib/pione/system/init.rb +3 -0
  148. data/lib/pione/system/normalizer.rb +40 -0
  149. data/lib/pione/system/status.rb +5 -5
  150. data/lib/pione/system/system-exception.rb +14 -1
  151. data/lib/pione/task-worker-broker.rb +7 -0
  152. data/lib/pione/task-worker-broker/basic-provider.rb +20 -0
  153. data/lib/pione/task-worker-broker/easy-provider.rb +65 -0
  154. data/lib/pione/test-helper.rb +27 -0
  155. data/lib/pione/test-helper/command-helper.rb +9 -101
  156. data/lib/pione/tuple-space/basic-tuple.rb +1 -1
  157. data/lib/pione/tuple-space/tuple-definition.yml +4 -6
  158. data/lib/pione/tuple-space/tuple-space-interface.rb +3 -45
  159. data/lib/pione/tuple-space/tuple-space-server.rb +45 -0
  160. data/lib/pione/util.rb +1 -2
  161. data/lib/pione/util/boolean-value.rb +62 -0
  162. data/lib/pione/util/completion.rb +111 -0
  163. data/lib/pione/util/evaluatable.rb +13 -27
  164. data/lib/pione/util/package-parameters-list.rb +15 -27
  165. data/lib/pione/util/zip.rb +8 -3
  166. data/lib/pione/version.rb +1 -1
  167. data/lib/rootage.rb +20 -0
  168. data/lib/rootage/action.rb +114 -0
  169. data/lib/rootage/argument.rb +46 -0
  170. data/lib/rootage/command.rb +218 -0
  171. data/lib/rootage/core.rb +532 -0
  172. data/lib/rootage/exception.rb +107 -0
  173. data/lib/rootage/help.rb +148 -0
  174. data/lib/rootage/help.txt.erb +31 -0
  175. data/lib/rootage/log.rb +226 -0
  176. data/lib/rootage/normalizer.rb +184 -0
  177. data/lib/rootage/option.rb +152 -0
  178. data/lib/rootage/scenario-test-result.erb +39 -0
  179. data/lib/rootage/scenario.rb +362 -0
  180. data/lib/rootage/test-helper.rb +115 -0
  181. data/man/pione-list-param.1 +44 -0
  182. data/misc/clock.rb +9 -0
  183. data/misc/machine-info.sh +21 -0
  184. data/misc/pione-completion.bash +238 -0
  185. data/misc/pione-completion.erb +53 -0
  186. data/misc/pione-completion.zsh +238 -0
  187. data/misc/pione.god +22 -0
  188. data/misc/ui.xml +23 -0
  189. data/pione.gemspec +3 -1
  190. data/test/agent/spec_basic-agent.rb +1 -1
  191. data/test/agent/spec_input-generator.rb +2 -2
  192. data/test/agent/spec_messenger.rb +6 -9
  193. data/test/agent/spec_notification-listener.rb +80 -0
  194. data/test/agent/{spec_broker.rb → spec_task-worker-broker.rb} +13 -10
  195. data/test/agent/spec_tuple-space-provider.rb +10 -6
  196. data/test/command/command-behavior.rb +3 -11
  197. data/test/command/data/pione-list-param/AdvancedParameters.pione +12 -0
  198. data/test/command/data/pione-list-param/BasicParameters.pione +12 -0
  199. data/test/command/spec_pione-action-exec.rb +16 -0
  200. data/test/command/spec_pione-action-list.rb +15 -10
  201. data/test/command/spec_pione-action-print.rb +14 -0
  202. data/test/command/spec_pione-action.rb +6 -19
  203. data/test/command/spec_pione-clean.rb +29 -46
  204. data/test/command/spec_pione-client.rb +29 -36
  205. data/test/command/spec_pione-command.rb +6 -6
  206. data/test/command/{spec_pione-compiler.rb → spec_pione-compile.rb} +11 -13
  207. data/test/command/spec_pione-config-get.rb +47 -0
  208. data/test/command/spec_pione-config-list.rb +42 -0
  209. data/test/command/spec_pione-config-set.rb +38 -0
  210. data/test/command/spec_pione-config-unset.rb +44 -0
  211. data/test/command/spec_pione-config.rb +11 -0
  212. data/test/command/spec_pione-diagnosis-notification.rb +23 -0
  213. data/test/command/spec_pione-diagnosis.rb +11 -0
  214. data/test/command/spec_pione-lang-check-syntax.rb +12 -0
  215. data/test/command/spec_pione-lang.rb +11 -0
  216. data/test/command/spec_pione-log-format.rb +29 -0
  217. data/test/command/spec_pione-log-list-id.rb +17 -0
  218. data/test/command/spec_pione-log.rb +6 -20
  219. data/test/command/spec_pione-package-add.rb +55 -0
  220. data/test/command/spec_pione-package-build.rb +57 -0
  221. data/test/command/spec_pione-package-show.rb +72 -0
  222. data/test/command/{spec_pione-update-package-info.rb → spec_pione-package-update.rb} +12 -13
  223. data/test/command/spec_pione-package.rb +4 -104
  224. data/test/command/spec_pione-val.rb +10 -7
  225. data/test/global/spec_config.rb +50 -0
  226. data/test/global/spec_item.rb +1 -1
  227. data/test/literate-action/data/HelloWorld.md +1 -1
  228. data/test/location/location-behavior.rb +1 -1
  229. data/test/location/spec_dropbox-location.rb +39 -0
  230. data/test/location/spec_notification-scheme.rb +37 -0
  231. data/test/log/spec_debug.rb +5 -4
  232. data/test/log/spec_message-log-receiver.rb +13 -0
  233. data/test/log/spec_message-log.rb +6 -9
  234. data/test/log/spec_system-log.rb +5 -3
  235. data/test/notification/spec_address.rb +229 -0
  236. data/test/notification/spec_message.rb +30 -0
  237. data/test/notification/spec_receiver.rb +36 -0
  238. data/test/notification/spec_transmitter.rb +37 -0
  239. data/test/pnml/data/ConditionalBranchIf.pnml +270 -0
  240. data/test/pnml/data/ConditionalBranchIfElse.pnml +309 -0
  241. data/test/pnml/data/IOExpansionComplex.pnml +363 -0
  242. data/test/pnml/data/IOExpansionSimple.pnml +140 -0
  243. data/test/pnml/data/InputMergeComplementComplex.pnml +381 -0
  244. data/test/pnml/data/InputMergeComplementSimple.pnml +248 -0
  245. data/test/pnml/data/InputParallelizationComplementComplex.pnml +433 -0
  246. data/test/pnml/data/InputParallelizationComplementSimple.pnml +288 -0
  247. data/test/pnml/data/InputReductionComplex.pnml +192 -0
  248. data/test/pnml/data/InputReductionLong.pnml +344 -0
  249. data/test/pnml/data/InputReductionSimple.pnml +140 -0
  250. data/test/pnml/data/IsolatedElementElimination.pnml +171 -0
  251. data/test/pnml/data/OutputDecompositionComplementComplex.pnml +381 -0
  252. data/test/pnml/data/OutputDecompositionComplementSimple.pnml +242 -0
  253. data/test/pnml/data/OutputReductionComplex.pnml +186 -0
  254. data/test/pnml/data/OutputReductionLong.pnml +344 -0
  255. data/test/pnml/data/OutputReductionSimple.pnml +140 -0
  256. data/test/pnml/data/OutputSynchronizationComplementComplex.pnml +498 -0
  257. data/test/pnml/data/OutputSynchronizationComplementSimple.pnml +347 -0
  258. data/test/pnml/data/SampleNet.pnml +238 -0
  259. data/test/pnml/spec_input-merge-complement.rb +40 -0
  260. data/test/pnml/spec_input-parallelization-complement.rb +50 -0
  261. data/test/pnml/spec_input-reduction.rb +113 -0
  262. data/test/pnml/spec_invalid-arc-elimination.rb +33 -0
  263. data/test/pnml/spec_io-expansion.rb +126 -0
  264. data/test/pnml/spec_isolated-element-elimination.rb +25 -0
  265. data/test/pnml/spec_output-decomposition-complement.rb +40 -0
  266. data/test/pnml/spec_output-reduction.rb +114 -0
  267. data/test/pnml/spec_output-synchronization-complement.rb +62 -0
  268. data/test/pnml/spec_pione-element.rb +144 -0
  269. data/test/pnml/spec_pnml-element.rb +373 -0
  270. data/test/pnml/spec_reader.rb +16 -0
  271. data/test/rootage/spec_argument.rb +18 -0
  272. data/test/rootage/spec_command.rb +239 -0
  273. data/test/rootage/spec_core.rb +198 -0
  274. data/test/rootage/spec_scenario.rb +149 -0
  275. data/test/system/{spec_domain-info.rb → spec_domain-dump.rb} +6 -6
  276. data/test/system/spec_file-cache.rb +6 -9
  277. data/test/tuple-space/spec_finished-tuple.rb +1 -1
  278. data/test/util/{spec_package-parameters-list_1.pione → data/package-parameters-list/Param1.pione} +0 -0
  279. data/test/util/{spec_package-parameters-list_2.pione → data/package-parameters-list/Param2.pione} +0 -0
  280. data/test/util/{spec_package-parameters-list_3.pione → data/package-parameters-list/Param3.pione} +0 -0
  281. data/test/util/{spec_package-parameters-list_4.pione → data/package-parameters-list/Param4.pione} +0 -0
  282. data/test/util/spec_boolean-value.rb +32 -0
  283. data/test/util/spec_completion.rb +22 -0
  284. data/test/util/spec_package-parameters-list.rb +39 -52
  285. data/test/util/spec_zip.rb +28 -1
  286. metadata +288 -47
  287. data/bin/pione-tuple-space-receiver +0 -5
  288. data/lib/pione/agent/broker.rb +0 -304
  289. data/lib/pione/agent/tuple-space-receiver.rb +0 -137
  290. data/lib/pione/command/pione-broker.rb +0 -104
  291. data/lib/pione/command/pione-compiler.rb +0 -57
  292. data/lib/pione/command/pione-relay-account-db.rb +0 -141
  293. data/lib/pione/command/pione-relay-client-db.rb +0 -118
  294. data/lib/pione/command/pione-relay.rb +0 -59
  295. data/lib/pione/command/pione-syntax-checker.rb +0 -214
  296. data/lib/pione/command/pione-tuple-space-receiver.rb +0 -111
  297. data/lib/pione/command/pione-update-package-info.rb +0 -53
  298. data/lib/pione/front/broker-front.rb +0 -22
  299. data/lib/pione/front/tuple-space-receiver-front.rb +0 -11
  300. data/lib/pione/global/broker-variable.rb +0 -33
  301. data/lib/pione/system/domain-info.rb +0 -25
  302. data/lib/pione/util/pnml-compiler.rb +0 -168
  303. data/test/agent/spec_tuple-space-receiver.rb +0 -47
  304. data/test/util/spec_pnml-compiler.rb +0 -32
@@ -0,0 +1,198 @@
1
+ module Pione
2
+ module Command
3
+ class BasicItem < StructX
4
+ # `name` is item name. This is used as a reference at controller.
5
+ member :name
6
+
7
+ # Attribute name in model.
8
+ member :model_name
9
+
10
+ # The action's description, this is shown in verbose help.
11
+ member :desc
12
+
13
+ # Context class, instance of this class is used as context of
14
+ # process. This context class should inherit `ProcessContext`.
15
+ member :context
16
+
17
+ # Processes, this includes blocks that is definded by #define_process,
18
+ # #define_assignment, and #define_condition
19
+ member :processes, :default => lambda {[]}
20
+
21
+ # Exception handlers.
22
+ member :exception_handlers, :default => lambda {[]}
23
+
24
+ # Define a process that is executed just after pre-process. This is used
25
+ # for setting values excluding command model, for example global values.
26
+ #
27
+ # @yieldparam val [Object]
28
+ # arbitrary value, this is passed from #execute
29
+ def process(&block)
30
+ self.processes << Proc.new do |cmd, args|
31
+ catch(:failure) do
32
+ create_context(cmd).instance_exec(*args, &block)
33
+ end
34
+ end
35
+ end
36
+
37
+ # Define an assignment process. This assigns the result value of the block
38
+ # to model. This is same as #action excluding model assignment.
39
+ #
40
+ # @param name [Symbol]
41
+ # attribute name in model
42
+ # @yieldparam val [Object]
43
+ # normalized option value
44
+ def assign(name=(self.model_name || self.name), &block)
45
+ self.processes << Proc.new do |cmd, args|
46
+ catch(:failure) do
47
+ res = create_context(cmd).instance_exec(cmd, *args, &block)
48
+ if name
49
+ cmd.model[name] = res
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Define a condition. This is a process simply, but goes to quit the whale
56
+ # action halfway if it fails.
57
+ #
58
+ # @yieldparam val [Object]
59
+ # arbitrary value, this is passed from #execute
60
+ def condition(&block)
61
+ self.processes << Proc.new do |cmd, args|
62
+ res = catch(:failure) do
63
+ create_context(cmd).instance_exec(*args, &block)
64
+ true
65
+ end
66
+ throw :quit unless res
67
+ end
68
+ end
69
+
70
+ # Define an exception handler.
71
+ #
72
+ # @param exceptions [Array<Class>]
73
+ # exception classes that handler should handle, that is assumed `StandardError` if empty
74
+ # @yieldparam e [Exception]
75
+ # raised exception object
76
+ # @yieldparam args [Array]
77
+ # arbitrary objects
78
+ def exception(*exceptions, &block)
79
+ if exceptions.empty?
80
+ exceptions = [StandardError]
81
+ end
82
+ self.exception_handlers << ExceptionHandler.new(exceptions, block)
83
+ end
84
+
85
+ # Copy the object. This is shallow copy, but arrays are cloned.
86
+ #
87
+ # @return [Command::BasicItem]
88
+ # copied object
89
+ def copy
90
+ self.class.new.tap do |obj|
91
+ self.each_pair do |key, val|
92
+ obj.set(key => val.is_a?(Array) ? val.clone : val)
93
+ end
94
+ end
95
+ end
96
+
97
+ # Execute the action.
98
+ #
99
+ # @param cmd [Command::PlainCommand]
100
+ # command
101
+ # @param args [Array]
102
+ # arbitrary objects, this is passed to process's block
103
+ # @return [void]
104
+ def execute(cmd, *args)
105
+ # catch "quit" message here
106
+ catch(:quit) do
107
+ processes.each {|block| block.call(cmd, args)}
108
+ end
109
+ rescue Exception => e
110
+ exception_handlers.find do |handler|
111
+ catch(:failure) { handler.try_to_handle(create_context(cmd), e, args) }
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ # Create a context object for processing.
118
+ #
119
+ # @param cmd [Command::PlainCommand]
120
+ # @return [ProcessContext]
121
+ # a context object for processing
122
+ def create_context(cmd)
123
+ (self.context || ProcessContext).new(cmd)
124
+ end
125
+ end
126
+
127
+ module CollectionInterface
128
+ attr_reader :items
129
+
130
+ def item_class
131
+ raise NotImplemented
132
+ end
133
+
134
+ # Define a new item.
135
+ def define(name, &b)
136
+ item = item_class.new.tap do |item|
137
+ item.name = name
138
+ b.call(item)
139
+ end
140
+
141
+ @items ||= []
142
+ @items << item
143
+
144
+ # define a getter method if this is a module
145
+ if self.kind_of?(Module)
146
+ singleton_class.send(:define_method, name) {item}
147
+ end
148
+ end
149
+
150
+ # Use the item as command option. If block is given, apply the block with
151
+ # cloned item and use it.
152
+ #
153
+ # @param item [OptionItem]
154
+ # option item
155
+ # @yield [item]
156
+ # the cloned item
157
+ def use(item, &b)
158
+ unless item.kind_of?(item_class)
159
+ raise ArgumentError.new(item)
160
+ end
161
+
162
+ if block_given?
163
+ _item = item.copy
164
+ b.call(_item)
165
+ @items << _item
166
+ else
167
+ @items << item
168
+ end
169
+
170
+ # define a getter method if this is a module
171
+ if self.kind_of?(Module)
172
+ singleton_class.send(:define_method, name) {item}
173
+ end
174
+ end
175
+ end
176
+
177
+ # `ExceptionHandler` is a handler of exception for action item.
178
+ class ExceptionHandler
179
+ def initialize(exceptions, block)
180
+ @exceptions = exceptions
181
+ @block = block
182
+ end
183
+
184
+ def try_to_handle(context, e, *args)
185
+ if @exceptions.any?{|ec| e.kind_of?(ec)}
186
+ handle(context, e, *args)
187
+ return true
188
+ end
189
+
190
+ return false
191
+ end
192
+
193
+ def handle(context, e, *args)
194
+ context.instance_exec(e, *args, &@block)
195
+ end
196
+ end
197
+ end
198
+ end
@@ -1,256 +1,211 @@
1
1
  module Pione
2
2
  module Command
3
- # OptionItem is an option item for PIONE command.
4
- class OptionItem < StructX
5
- member :name # option name
6
- member :short # short option (same as standard OptionParser)
7
- member :long # long option (same as standard OptionParser)
8
- member :desc # option description (same as standard OpionParser)
9
- member :default # default value
10
- member :value # value
11
- member :values # ???
12
- member :action # option action
13
- member :validator # option validator
14
- member :requisite # requisite option flag
15
- end
3
+ # CommonOption provides common options for almost pione commands.
4
+ module CommonOption
5
+ extend Rootage::OptionCollection
16
6
 
17
- # OptionInterface provides basic methods for option modules. All option
18
- # modules should be extended by this.
19
- module OptionInterface
20
- attr_reader :items
7
+ define(:color) do |item|
8
+ item.type = :boolean
9
+ item.long = '--color'
10
+ item.arg = 'BOOLEAN'
11
+ item.desc = 'Turn on/off color mode'
21
12
 
22
- # Define a new option for the command.
23
- def define(name, &b)
24
- item = OptionItem.new.tap do |item|
25
- item.name = name
26
- b.call(item)
27
- end
13
+ item.process {|val| Global.color_enabled = val}
14
+ end
28
15
 
29
- if self.kind_of?(Module)
30
- singleton_class.send(:define_method, name) {item}
31
- else
32
- @items << item
16
+ define(:debug) do |item|
17
+ item.type = :string
18
+ item.range =
19
+ ["system", "rule_engine", "ignored_exception", "notification", "communication"]
20
+ item.long = '--debug'
21
+ item.arg = '[TYPE]'
22
+ item.desc = "Turn on debug mode about the type"
23
+ item.default = "system"
24
+
25
+ item.process do |type|
26
+ Global.system_logger.level = :debug
27
+ case type
28
+ when "system", nil
29
+ Global.debug_system = true
30
+ when "rule_engine"
31
+ Global.debug_rule_engine = true
32
+ when "notification"
33
+ Global.debug_notification = true
34
+ when "communication"
35
+ Global.debug_communication = true
36
+ when "ignored_exception"
37
+ Global.debug_ignored_exception = true
38
+ else
39
+ raise OptionError.new(cmd, 'Unknown debug type "%s"' % type)
40
+ end
33
41
  end
34
42
  end
35
43
 
36
- # Install the option module with configuration +option+.
37
- def use(item_name, option={})
38
- @items << CommonOption.send(item_name).set(option)
44
+ define(:features) do |item|
45
+ item.type = :string
46
+ item.long = '--features'
47
+ item.arg = 'FEATURES'
48
+ item.desc = 'Set features'
49
+
50
+ item.process {|val| Global.features = val}
51
+
52
+ item.exception(Parslet::ParseFailed) do |e, val|
53
+ arg = {features: val, reason: e.message}
54
+ raise OptionError.new(
55
+ cmd, 'The feature expression "%{features}" is invalid: %{reason}' % arg
56
+ )
57
+ end
39
58
  end
40
- end
41
59
 
42
- # OptionDefinition is a class for holding option definitions.
43
- class OptionDefinition
44
- attr_accessor :parser_mode
45
-
46
- # Creata a command option context.
47
- def initialize
48
- extend OptionInterface
49
- @items = [] # option item definitions
50
- @default = {} # default value table
51
- @validators = [] # option validators
52
- @parser_mode = :parse!
53
- end
60
+ define(:communication_address) do |item|
61
+ item.type = :uri
62
+ item.long = "--communication-address"
63
+ item.arg = 'URI'
64
+ item.desc = "Set the IP address for interprocess communication"
54
65
 
55
- def item(name)
56
- @items.find {|item| item.name == name}
66
+ item.process {|address| Global.communication_address = address}
57
67
  end
58
68
 
59
- # Parse the command options.
60
- def parse(argv, command_name, command_banner)
61
- data = Hash.new
62
-
63
- # parse options
64
- OptionParser.new do |opt|
65
- # set banner
66
- opt.banner = "Usage: %s [options]" % command_name
67
- opt.banner << "\n\n" + command_banner + "\n" if command_banner
68
-
69
- # set version
70
- opt.program_name = command_name
71
- opt.version = Pione::VERSION
72
-
73
- # default values
74
- @items.each {|item| data[item.name] = item.default if item.default}
75
- data.merge!(@default)
76
-
77
- # setup option parser
78
- @items.sort{|a,b| a.long <=> b.long}.each {|item| setup_item(command_name, opt, data, item)}
79
- end.send(@parser_mode, argv)
69
+ define(:parent_front) do |item|
70
+ item.type = :uri
71
+ item.long = '--parent-front'
72
+ item.arg = 'URI'
73
+ item.desc = 'set parent front URI'
80
74
 
81
- # check option's validness
82
- check(data)
75
+ item.assign {|uri| DRbObject.new_with_uri(uri.to_s)}
83
76
 
84
- return data
85
- end
77
+ item.process do |uri|
78
+ timeout(1) {model[:parent_front].ping}
79
+ end
86
80
 
87
- # Define the default value.
88
- def default(name, value)
89
- @default[name] = value
81
+ item.exception(Exception) do |e, uri|
82
+ arg = {name: cmd.name, uri: uri.to_s, reason: e.message}
83
+ raise HideableOptionError.new(
84
+ cmd, '"%{name}" has failed to connect to parent front "%{uri}": %{reason}' % arg
85
+ )
86
+ end
90
87
  end
91
88
 
92
- def validate(&b)
93
- @validators << b
89
+ define(:task_worker_size) do |item|
90
+ item.type = :integer
91
+ item.short = '-t'
92
+ item.long = '--task-worker-size'
93
+ item.arg = 'N'
94
+ item.desc = 'Set task worker size that this process creates'
95
+ item.init = [Util::CPU.core_number - 1, 1].max
94
96
  end
95
97
 
96
- private
97
-
98
- # Setup the option item.
99
- def setup_item(command_name, opt, data, item)
100
- defs = [item.short, item.long, item.desc].compact
101
- [ :setup_item_action,
102
- :setup_item_values,
103
- :setup_item_value,
104
- :setup_item_static_value
105
- ].find {|method_name| send(method_name, command_name, opt, data, item, defs)}
106
- end
98
+ define(:domain_dump_location) do |item|
99
+ item.type = :location
100
+ item.long = '--domain-dump'
101
+ item.arg = 'LOCATION'
102
+ item.desc = 'Import the domain dump file'
107
103
 
108
- def setup_item_action(command_name, opt, data, item, defs)
109
- if item.action
110
- opt.on(*defs, Proc.new{|*args| self.instance_exec(command_name, data, *args, &item.action)})
104
+ item.process do |location|
105
+ unless location.exist?
106
+ raise OptionError.new(
107
+ cmd, 'The location doesn\'t exist: %{location}' % {location: location}
108
+ )
109
+ end
111
110
  end
112
- end
113
111
 
114
- def setup_item_values(command_name, opt, data, item, defs)
115
- if item.values.kind_of?(Proc)
116
- opt.on(*defs, Proc.new{|*args| data[item.name] << self.instance_exec(*args, &item.values)})
112
+ item.assign(:domain_dump_location) do |location|
113
+ test(location.file?)
114
+ location
117
115
  end
118
- end
119
116
 
120
- def setup_item_value(command_name, opt, data, item, defs)
121
- case item.value
122
- when Proc
123
- opt.on(*defs, Proc.new{|*args| data[item.name] = self.instance_exec(*args, &item.value)})
124
- when :as_is
125
- opt.on(*defs, Proc.new{|*args| data[item.name] = args.first})
117
+ item.assign(:domain_dump_location) do |location|
118
+ test(location.directory?)
119
+
120
+ # find default domain dump file
121
+ _location = location + System::DomainDump::FILENAME
122
+ if _location.exist?
123
+ _location
124
+ else
125
+ raise OptionError.new(
126
+ cmd, 'The location doesn\'t exist: %{location}' % {location: _location}
127
+ )
128
+ end
126
129
  end
127
130
  end
128
131
 
129
- def setup_item_static_value(command_name, opt, data, item, defs)
130
- if item.value
131
- opt.on(*defs, Proc.new{ data[item.name] = item.value})
132
+ define(:file_cache_method) do |item|
133
+ item.type = :symbol
134
+ item.long = '--file-cache-method'
135
+ item.arg = 'NAME'
136
+ item.desc = 'use NAME as a file cache method'
137
+
138
+ item.process do |name|
139
+ System::FileCache.set_cache_method(name)
132
140
  end
133
141
  end
134
142
 
135
- # Check validness of the command options.
136
- def check(data)
137
- # check requisite options
138
- @items.each do |item|
139
- if item.requisite and not(data[item.name])
140
- raise OptionError.new("option \"%s\" is requisite" % [item.long])
141
- end
142
- end
143
+ define(:file_sliding) do |item|
144
+ item.type = :boolean
145
+ item.long = '--file-sliding'
146
+ item.arg = '[BOOLEAN]'
147
+ item.desc = 'Enable/disable to slide files in file server'
148
+ item.default = true
143
149
 
144
- # apply validators
145
- @validators.each {|validator| validator.call(data)}
150
+ item.process do |val|
151
+ Global.file_sliding = val
152
+ end
146
153
  end
147
154
  end
148
155
 
149
- # CommonOption provides common options for pione commands.
150
- module CommonOption
151
- extend OptionInterface
156
+ # `NotificationOption` provides for notification options.
157
+ module NotificationOption
158
+ extend Rootage::OptionCollection
152
159
 
153
- define(:color) do |item|
154
- item.long = '--[no-]color'
155
- item.desc = 'turn on/off color mode'
156
- item.action = proc {|_, _, bool|
157
- Global.color_enabled = bool
158
- Sickill::Rainbow.enabled = bool
159
- }
160
- end
160
+ define(:notification_targets) do |item|
161
+ item.type = :string
162
+ item.long = '--notification-target'
163
+ item.arg = 'URI'
164
+ item.desc = 'Target address that notifications are sent to'
165
+ item.init = Global.notification_targets
161
166
 
162
- define(:daemon) do |item|
163
- item.long = "--daemon"
164
- item.desc = "turn on daemon mode"
165
- item.default = false
166
- item.value = true
167
- end
167
+ item.assign(:__defined_notification_targets__) do |address|
168
+ test(not(model[:__defined_notification_targets__]))
168
169
 
169
- define(:debug) do |item|
170
- item.long = '--debug[=TYPE]'
171
- item.desc = "turn on debug mode about the type(system / rule_engine / ignored_exception / presence_notifier / communication)"
172
- item.action = proc {|command_nane, _, type|
173
- Global.system_logger.level = :debug
174
- case type
175
- when "system", nil
176
- Global.debug_system = true
177
- when "rule_engine"
178
- Global.debug_rule_engine = true
179
- when "presence_notification"
180
- Global.debug_presence_notification = true
181
- when "communication"
182
- Global.debug_communication = true
183
- when "ignored_exception"
184
- Global.debug_ignored_exception = true
170
+ Global.notification_targets.clear
171
+ true
172
+ end
173
+
174
+ item.process do |address|
175
+ uri = Notification::Address.target_address_to_uri(address.strip)
176
+ if ["pnb", "pnm", "pnu"].include?(uri.scheme)
177
+ Global.notification_targets << uri
185
178
  else
186
- raise OptionError.new("option error: unknown debug type \"=%s\"" % type)
179
+ cmd.abort('"%s" seems not to be a notification address.' % address)
187
180
  end
188
- }
181
+ end
189
182
  end
190
183
 
191
- define(:features) do |item|
192
- item.long = '--features=FEATURES'
193
- item.desc = 'set features'
194
- item.action = proc {|command_name, option, features|
195
- begin
196
- # store features
197
- Global.features = features
198
- rescue Parslet::ParseFailed => e
199
- raise OptionError.new(
200
- "invalid feature expression \"%s\" is given for %s" % [features, command_name]
201
- )
202
- end
203
- }
204
- end
184
+ define(:notification_receivers) do |item|
185
+ item.type = :string
186
+ item.long = "--notification-receiver"
187
+ item.arg = "URI"
188
+ item.desc = "Receiver address that notifications are received at"
189
+ item.init = Global.notification_receivers
205
190
 
206
- define(:my_ip_address) do |item|
207
- item.long = "--my-ip-address=ADDRESS"
208
- item.desc = "set my IP address"
209
- item.action = proc {|_, _, address| Global.my_ip_address = address}
210
- end
191
+ # clear default notification address
192
+ item.assign(:__defined_notification_receivers__) do |address|
193
+ test(not(model[:__defined_notification_receivers__]))
211
194
 
212
- define(:parent_front) do |item|
213
- item.long = '--parent-front=URI'
214
- item.desc = 'set parent front URI'
215
- item.requisite = true
216
- item.action = proc do |command_name, option, uri|
217
- begin
218
- option[:parent_front] = DRbObject.new_with_uri(uri)
219
- timeout(1) {option[:parent_front].ping}
220
- rescue Exception => e
221
- raise HideableOptionError.new(
222
- "%s couldn't connect to parent front \"%s\": %s" % [command_name, uri, e.message]
223
- )
224
- end
195
+ Global.notification_receivers.clear
196
+ true
225
197
  end
226
- end
227
198
 
228
- define(:presence_notification_address) do |item|
229
- item.long = "--presence-notification-address=255.255.255.255:%s" % Global.presence_port
230
- item.desc = "set the address for sending presence notifier"
231
- item.action = proc do |_, _, address|
232
- # clear addresses at first time
233
- unless @__option_notifier_address__
234
- @__option_notifier_address__ = true
235
- Global.presence_notification_addresses = []
199
+ # check the address and append it to receivers
200
+ item.process do |address|
201
+ uri = Notification::Address.receiver_address_to_uri(address.strip)
202
+ if ["pnb", "pnm", "pnu"].include?(uri.scheme)
203
+ Global.notification_receivers << uri
204
+ else
205
+ cmd.abort('"%s" seems not to be a notification address.' % address)
236
206
  end
237
-
238
- # add the address
239
- address = address =~ /^broadcast/ ? address : "broadcast://%s" % address
240
- uri = URI.parse(address)
241
- uri.host = "255.255.255.255" if uri.host.nil?
242
- uri.port = Global.presence_port if uri.port.nil?
243
- Global.presence_notification_addresses << uri
244
207
  end
245
208
  end
246
-
247
- define(:task_worker) do |item|
248
- item.short = '-t N'
249
- item.long = '--task-worker=N'
250
- item.desc = 'set task worker number that this process creates'
251
- item.default = [Util::CPU.core_number - 1, 1].max
252
- item.value = proc {|n| n.to_i}
253
- end
254
209
  end
255
210
  end
256
211
  end