unageanu-jiji 1.1.4 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. data/ChangeLog +24 -1
  2. data/README +0 -0
  3. data/base/shared_lib/moving_average.rb +34 -33
  4. data/base/shared_lib/system/cross.rb +76 -0
  5. data/base/shared_lib/system/position_manager.rb +160 -0
  6. data/base/shared_lib/system/signal.rb +347 -0
  7. data/html/css/datatable.css +4 -4
  8. data/html/css/default.css +57 -5
  9. data/html/css/treeview.css +205 -0
  10. data/html/img/bin_closed.png +0 -0
  11. data/html/img/bin_empty.png +0 -0
  12. data/html/img/button_add_small.gif +0 -0
  13. data/html/img/button_add_small_gray.gif +0 -0
  14. data/html/img/button_add_small_over.gif +0 -0
  15. data/html/img/button_mkcol.gif +0 -0
  16. data/html/img/button_mkcol_gray.gif +0 -0
  17. data/html/img/button_mkcol_over.gif +0 -0
  18. data/html/img/button_remove_small.gif +0 -0
  19. data/html/img/button_remove_small_gray.gif +0 -0
  20. data/html/img/button_remove_small_over.gif +0 -0
  21. data/html/img/button_rename.gif +0 -0
  22. data/html/img/button_rename_gray.gif +0 -0
  23. data/html/img/button_rename_over.gif +0 -0
  24. data/html/img/control_play.png +0 -0
  25. data/html/img/control_play_blue.png +0 -0
  26. data/html/img/folder.png +0 -0
  27. data/html/img/folder_brick.png +0 -0
  28. data/html/img/folder_user.png +0 -0
  29. data/html/{js/codepress/images → img}/line-numbers.png +0 -0
  30. data/html/img/page_white_ruby.png +0 -0
  31. data/html/img/sidebar_agent_edit.png +0 -0
  32. data/html/img/sidebar_agent_edit_over.png +0 -0
  33. data/html/img/sidebar_agent_edit_s.png +0 -0
  34. data/html/img/yui/treeview-sprite.gif +0 -0
  35. data/html/index.html +34 -18
  36. data/html/js/agent-editor/agent-editor-page.js +324 -0
  37. data/html/js/agent-editor/agent-editor.js +363 -0
  38. data/html/js/agent-editor/agent-list-tree.js +251 -0
  39. data/html/js/agent-selector.js +23 -28
  40. data/html/js/app.js +63 -91
  41. data/html/js/bt-create-page.js +25 -19
  42. data/html/js/container-min.js +1 -1
  43. data/html/js/container.js +944 -0
  44. data/html/js/edit_area/autocompletion.js +11 -13
  45. data/html/js/edit_area/edit_area.css +79 -40
  46. data/html/js/edit_area/edit_area.js +255 -226
  47. data/html/js/edit_area/edit_area_compressor.php +4 -4
  48. data/html/js/edit_area/edit_area_full.gz +0 -0
  49. data/html/js/edit_area/edit_area_full.js +31 -31
  50. data/html/js/edit_area/edit_area_full_with_plugins.gz +0 -0
  51. data/html/js/edit_area/edit_area_full_with_plugins.js +31 -31
  52. data/html/js/edit_area/edit_area_functions.js +448 -341
  53. data/html/js/edit_area/edit_area_loader.js +409 -397
  54. data/html/js/edit_area/elements_functions.js +120 -123
  55. data/html/js/edit_area/highlight.js +305 -197
  56. data/html/js/edit_area/images/goto.png +0 -0
  57. data/html/js/edit_area/images/help.png +0 -0
  58. data/html/js/edit_area/images/redo.png +0 -0
  59. data/html/js/edit_area/images/save.png +0 -0
  60. data/html/js/edit_area/images/search.png +0 -0
  61. data/html/js/edit_area/images/undo.png +0 -0
  62. data/html/js/edit_area/images/word_wrap.gif +0 -0
  63. data/html/js/edit_area/keyboard.js +5 -5
  64. data/html/js/edit_area/langs/bg.js +73 -0
  65. data/html/js/edit_area/langs/cs.js +2 -0
  66. data/html/js/edit_area/langs/de.js +2 -0
  67. data/html/js/edit_area/langs/dk.js +2 -0
  68. data/html/js/edit_area/langs/en.js +2 -0
  69. data/html/js/edit_area/langs/eo.js +2 -0
  70. data/html/js/edit_area/langs/es.js +2 -0
  71. data/html/js/edit_area/langs/fi.js +67 -0
  72. data/html/js/edit_area/langs/fr.js +2 -0
  73. data/html/js/edit_area/langs/hr.js +2 -0
  74. data/html/js/edit_area/langs/it.js +2 -0
  75. data/html/js/edit_area/langs/ja.js +2 -0
  76. data/html/js/edit_area/langs/mk.js +2 -0
  77. data/html/js/edit_area/langs/nl.js +2 -0
  78. data/html/js/edit_area/langs/pl.js +2 -0
  79. data/html/js/edit_area/langs/pt.js +2 -0
  80. data/html/js/edit_area/langs/ru.js +2 -0
  81. data/html/js/edit_area/langs/sk.js +2 -0
  82. data/html/js/edit_area/langs/zh.js +67 -0
  83. data/html/js/edit_area/manage_area.js +362 -205
  84. data/html/js/edit_area/plugins/charmap/langs/bg.js +12 -0
  85. data/html/js/edit_area/plugins/charmap/langs/zh.js +6 -0
  86. data/html/js/edit_area/plugins/test/langs/bg.js +10 -0
  87. data/html/js/edit_area/plugins/test/langs/zh.js +4 -0
  88. data/html/js/edit_area/reg_syntax/java.js +56 -0
  89. data/html/js/edit_area/reg_syntax/ruby.js +9 -9
  90. data/html/js/edit_area/reg_syntax.js +15 -13
  91. data/html/js/edit_area/regexp.js +36 -32
  92. data/html/js/edit_area/resize_area.js +43 -47
  93. data/html/js/edit_area/search_replace.js +29 -29
  94. data/html/js/edit_area/template.html +6 -4
  95. data/html/js/json-broker-client.js +23 -17
  96. data/html/js/result-page.js +107 -57
  97. data/html/js/rt-setting-page.js +38 -15
  98. data/html/js/sidebar.js +41 -27
  99. data/html/js/templates.js +167 -32
  100. data/html/js/utils.js +143 -7
  101. data/html/js/yui/treeview.js +3671 -0
  102. data/html/swf/chart.swf +0 -0
  103. data/html/test/agent_editor_spec.js +815 -0
  104. data/html/test/index.html +40 -0
  105. data/html/test/jsspec/JSSpec.css +224 -0
  106. data/html/test/jsspec/JSSpec.js +1549 -0
  107. data/html/test/jsspec/diff_match_patch.js +1 -0
  108. data/html/test/utils_spec.js +111 -0
  109. data/lib/jiji/agent/agent.rb +69 -12
  110. data/lib/jiji/agent/agent_manager.rb +18 -12
  111. data/lib/jiji/agent/agent_registry.rb +35 -121
  112. data/lib/jiji/collector.rb +16 -6
  113. data/lib/jiji/command.rb +46 -5
  114. data/lib/jiji/dao/file_system_dao.rb +158 -0
  115. data/lib/jiji/dao/timed_data_dao.rb +2 -0
  116. data/lib/jiji/dao/trade_result_dao.rb +1 -1
  117. data/lib/jiji/error.rb +24 -8
  118. data/lib/jiji/migration/migrator1_2_0.rb +67 -0
  119. data/lib/jiji/models.rb +82 -24
  120. data/lib/jiji/operator.rb +55 -51
  121. data/lib/jiji/output.rb +85 -29
  122. data/lib/jiji/output_manager.rb +84 -0
  123. data/lib/jiji/plugin/embedded/single_click_client.rb +2 -2
  124. data/lib/jiji/plugin/securities_plugin.rb +0 -1
  125. data/lib/jiji/process.rb +229 -208
  126. data/lib/jiji/process_manager.rb +190 -96
  127. data/lib/jiji/registry.rb +87 -19
  128. data/lib/jiji/server.rb +1 -0
  129. data/lib/jiji/service/agent_service.rb +147 -48
  130. data/lib/jiji/service/output_service.rb +37 -17
  131. data/lib/jiji/service/process_service.rb +3 -5
  132. data/lib/jiji/service/trade_result_service.rb +4 -5
  133. data/lib/jiji/util/file_lock.rb +4 -4
  134. data/lib/jiji/util/include_proxy.rb +17 -0
  135. data/lib/jiji/util/json_broker.rb +6 -4
  136. data/lib/jiji/util/util.rb +1 -1
  137. data/swf/chart/fx/chart/Chart.as +7 -0
  138. data/swf/chart/fx/chart/ui/graph/GraphManager.as +15 -2
  139. data/test/ProcessTest/agents/foo.rb +10 -0
  140. data/test/ProcessTest/conf/configuration.yaml +3 -0
  141. data/test/agent/agent_tests.rb +10 -0
  142. data/test/agent/test_AgentManager.rb +28 -12
  143. data/test/agent/test_AgentRegistry.rb +194 -99
  144. data/test/agent/test_PeriodicallyAgent.rb +1 -2
  145. data/test/agent/test_Permitter.rb +1 -2
  146. data/test/all_tests.rb +7 -19
  147. data/test/dao/dao_tests.rb +9 -0
  148. data/test/dao/test_FileSystemDao.rb +431 -0
  149. data/test/dao/test_RateDao.rb +5 -7
  150. data/test/dao/test_TradeResultDao.rb +1 -2
  151. data/test/migration/migration_tests.rb +10 -0
  152. data/test/migration/migrator1_2_0test_data/basic/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  153. data/test/migration/migrator1_2_0test_data/basic/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  154. data/test/migration/migrator1_2_0test_data/basic/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  155. data/test/migration/migrator1_2_0test_data/basic/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  156. data/test/migration/migrator1_2_0test_data/basic/props.yaml +85 -0
  157. data/test/migration/migrator1_2_0test_data/illegal_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  158. data/test/migration/migrator1_2_0test_data/illegal_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  159. data/test/migration/migrator1_2_0test_data/illegal_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  160. data/test/migration/migrator1_2_0test_data/illegal_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  161. data/test/migration/migrator1_2_0test_data/illegal_props/props.yaml +1 -0
  162. data/test/migration/migrator1_2_0test_data/no_outs/props.yaml +85 -0
  163. data/test/migration/migrator1_2_0test_data/no_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  164. data/test/migration/migrator1_2_0test_data/no_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  165. data/test/migration/migrator1_2_0test_data/no_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  166. data/test/migration/migrator1_2_0test_data/no_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  167. data/test/migration/test_Migrator.rb +1 -1
  168. data/test/migration/test_Migrator1_0_3.rb +1 -1
  169. data/test/migration/test_Migrator1_1_0.rb +1 -1
  170. data/test/migration/test_Migrator1_2_0.rb +94 -0
  171. data/test/plugin/embedded/test_SingleClickClient.rb +1 -2
  172. data/test/plugin/plugin_tests.rb +8 -0
  173. data/test/plugin/test_Loader.rb +1 -1
  174. data/test/shared/rate.csv +144 -0
  175. data/test/shared/shared_tests.rb +9 -0
  176. data/test/shared/test_Cross.rb +144 -0
  177. data/test/shared/test_PositionManager.rb +285 -0
  178. data/test/shared/test_Signal.rb +65 -0
  179. data/test/test_Output.rb +28 -21
  180. data/test/test_OutputManager.rb +162 -0
  181. data/test/test_Output_registry.rb +6 -17
  182. data/test/test_Process.rb +434 -222
  183. data/test/test_ProcessManager.rb +458 -101
  184. data/test/test_utils.rb +71 -8
  185. data/test/util/test_BlockToSession.rb +1 -2
  186. data/test/util/test_CSV.rb +1 -2
  187. data/test/util/test_SynchronizeInterceptor.rb +1 -2
  188. data/test/util/util_tests.rb +9 -0
  189. metadata +127 -47
  190. data/html/js/agent-editor-page.js +0 -440
  191. data/html/js/codepress/codepress.css +0 -21
  192. data/html/js/codepress/codepress.html +0 -35
  193. data/html/js/codepress/codepress.js +0 -138
  194. data/html/js/codepress/engines/gecko.js +0 -293
  195. data/html/js/codepress/engines/khtml.js +0 -0
  196. data/html/js/codepress/engines/msie.js +0 -304
  197. data/html/js/codepress/engines/older.js +0 -0
  198. data/html/js/codepress/engines/opera.js +0 -260
  199. data/html/js/codepress/images/line-numbers.gif +0 -0
  200. data/html/js/codepress/index.html +0 -443
  201. data/html/js/codepress/languages/asp.css +0 -71
  202. data/html/js/codepress/languages/asp.js +0 -117
  203. data/html/js/codepress/languages/autoit.css +0 -13
  204. data/html/js/codepress/languages/autoit.js +0 -32
  205. data/html/js/codepress/languages/csharp.css +0 -9
  206. data/html/js/codepress/languages/csharp.js +0 -25
  207. data/html/js/codepress/languages/css.css +0 -10
  208. data/html/js/codepress/languages/css.js +0 -23
  209. data/html/js/codepress/languages/generic.css +0 -9
  210. data/html/js/codepress/languages/generic.js +0 -25
  211. data/html/js/codepress/languages/html.css +0 -13
  212. data/html/js/codepress/languages/html.js +0 -59
  213. data/html/js/codepress/languages/java.css +0 -7
  214. data/html/js/codepress/languages/java.js +0 -24
  215. data/html/js/codepress/languages/javascript.css +0 -8
  216. data/html/js/codepress/languages/javascript.js +0 -30
  217. data/html/js/codepress/languages/perl.css +0 -11
  218. data/html/js/codepress/languages/perl.js +0 -27
  219. data/html/js/codepress/languages/php.css +0 -12
  220. data/html/js/codepress/languages/php.js +0 -61
  221. data/html/js/codepress/languages/ruby.css +0 -10
  222. data/html/js/codepress/languages/ruby.js +0 -26
  223. data/html/js/codepress/languages/sql.css +0 -10
  224. data/html/js/codepress/languages/sql.js +0 -30
  225. data/html/js/codepress/languages/text.css +0 -5
  226. data/html/js/codepress/languages/text.js +0 -9
  227. data/html/js/codepress/languages/vbscript.css +0 -71
  228. data/html/js/codepress/languages/vbscript.js +0 -117
  229. data/html/js/codepress/languages/xsl.css +0 -15
  230. data/html/js/codepress/languages/xsl.js +0 -103
  231. data/html/js/codepress/license.txt +0 -458
  232. data/html/js/edit_area/images/Thumbs.db +0 -0
  233. data/test/plugin/test_gem/a/lib/jiji_plugin_test.rb +0 -6
data/lib/jiji/process.rb CHANGED
@@ -1,213 +1,234 @@
1
-
1
+
2
2
  require 'jiji/agent/agent'
3
3
  require 'jiji/agent/agent_manager'
4
4
  require 'jiji/agent/agent_registry'
5
5
  require 'jiji/agent/permitter'
6
- require 'jiji/agent/util'
7
- require 'jiji/util/file_lock'
8
- require 'set'
9
- require "thread"
10
-
11
- module JIJI
12
-
13
- # プロセス
14
- class Process
15
-
16
- # コンストラクタ
17
- # 再起動後の復元の場合、プロパティを指定しないこと。この場合設定ファイルからロードされる。
18
- def initialize( id, process_dir, agent_manager, logger, props=nil, registry=nil, rmt=false )
19
-
20
- is_recreate = props == nil
21
- @logger = logger
22
- @registry = registry
23
- @id = id
24
- @agent_manager = agent_manager
25
- @process_dir = process_dir
26
- @started_mutex = Mutex.new
27
- @started_mutex.synchronize {
28
- @started= false
29
- }
30
- FileUtils.mkdir_p dir
31
-
32
- prop_file = "#{dir}/props.yaml"
33
- if !is_recreate
34
- @props = props
35
- @props["agents"] = [] unless @props.key? "agents"
36
- save_props
37
- else
38
- # 既存のプロセスの場合、ファイルから設定値を読み込む
39
- @props = {}
40
- lock {
41
- if ( File.exist? prop_file )
42
- @props = YAML.load_file prop_file
43
- end
44
- }
45
- @props["agents"] = [] unless @props.key? "agents"
46
- end
47
-
48
- # RMTまたは新規作成の場合はエージェントをロード
49
- # 再起動後の再作成時は、アウトプットのみ作成。
50
- @outputs = {}
51
- if rmt || !is_recreate
52
- load_agent(rmt) # リアル取引の再起動時は発生したエラーを無視する
53
- else
54
- if @props && @props["agents"]
55
- @props["agents"].each {|v|
56
- @outputs[v["id"]] = @registry.output( @id, v["name"] )
57
- }
58
- end
59
- end
60
-
61
- # 取引の有効状態を更新
62
- @agent_manager.operator.trade_enable =
63
- @props["trade_enable"] ? true : false
64
-
65
- end
66
-
67
- def start
68
- @started_mutex.synchronize {
69
- @started= true
70
- collector.listeners << self
71
- collector.start
72
- }
73
- # 状態を覚えておく
74
- self["state"] = collector.state
75
- end
76
-
77
- def stop
78
- @started_mutex.synchronize {
79
- if @started # 起動していない場合は何もしない
80
- observer_manager.stop
81
- collector.stop
82
-
83
- # 状態を覚えておく
84
- self["state"] = collector.state
85
- @started = false
86
- else
87
- # 待機中の場合、キャンセル状態にする。
88
- if props["state"] == :WAITING
89
- self["state"] = :CANCELED
90
- end
91
- end
92
- }
93
- collector.logger.close
94
- end
95
-
96
- def state
97
- # 再起動後のバックテストは、コレクターが起動しない
98
- # 状態は記録されたデータから返す
99
- if !@started
100
- return props["state"] ? props["state"] : :CANCELED
101
- else
102
- return collector.state
103
- end
104
- end
105
-
106
- def progress
107
- # 再起動後のバックテストは、コレクターが起動しない
108
- # 進捗は常に100%とする
109
- if !@started
110
- 100
111
- else
112
- collector.progress
113
- end
114
- end
115
-
116
- def []=(k,v)
117
- if ( k == "agents" )
118
- # エージェントの設定が更新された
119
- # 削除対象を特定するため、登録済みエージェントのIDのセットを作成
120
- set = agent_manager.inject(Set.new) { |s, pair| s << pair[0] }
121
- v.each {|item|
122
- # プロパティの更新 / 対応するエージェントが存在しなければ作成。
123
- set_agent_properties( item["id"], item["properties"], item["class"] )
124
- set.delete item["id"]
125
- }
126
- # Mapに含まれていないエージェントは削除
127
- set.each { |id|
128
- agent_manager.remove( id )
129
- outputs.delete( id )
130
- }
131
- end
132
- if ( k == "trade_enable" )
133
- # 取引の有効状態を更新
134
- @agent_manager.operator.trade_enable = v ? true : false
135
- end
136
- @props[k] = v
137
- save_props
138
- end
139
- def [](k)
140
- @props[k]
141
- end
142
-
143
- # コレクターの終了通知を受け取る
144
- def on_finished( state, now )
145
- self["state"] = state
146
- agent_manager.flush( now )
147
- end
148
-
149
-
150
- attr :id, true
151
- attr :props, true
152
- attr :collector, true
153
- attr :observer_manager, true
154
- attr :process_dir, true
155
- attr :agent_manager, true
156
- attr :outputs, true
157
- attr :logger, true
158
- attr :registry, true
159
-
160
- private
161
-
162
- # 任意のエージェントの設定を更新する。
163
- # エージェントは初期化されない。propertiesのみ変更される。
164
- def set_agent_properties( id, props, cl )
165
- a = agent_manager.get(id)
166
- if a
167
- a.agent.properties = props
168
- else
169
- agent = agent_manager.agent_registry.create( cl, props )
170
- agent_manager.add( id, agent, props["name"] )
171
- @outputs[id] = agent.output
172
- end
173
- end
174
-
175
- def dir
176
- "#{@process_dir}/#{@id}"
177
- end
178
- def lock
179
- DirLock.new( dir ).writelock {
180
- yield
181
- }
182
- end
183
- def save_props
184
- prop_file = "#{dir}/props.yaml"
185
- lock {
186
- File.open( prop_file, "w" ) { |f|
187
- f.write( YAML.dump(@props) )
188
- }
189
- }
190
- end
191
- def load_agent( ignore_error=false )
192
- @agent_manager.clear
193
- if @props && @props["agents"]
194
- @props["agents"].each {|v|
195
- begin
196
- agent = agent_manager.agent_registry.create( v["class"], v["properties"] )
197
- agent_manager.add( v["id"], agent, v["name"] )
198
- @outputs[v["id"]] = agent.output
199
- rescue Exception
200
- unless ignore_error
201
- raise $!
202
- else
203
- @logger.error $!
204
- end
205
- # リアルトレードの場合、停止中にエージェントが破棄された場合を考慮し
206
- # エージェントの初期化で失敗しても無視し、出力先だけ作成
207
- @outputs[v["id"]] = @registry.output( @id, v["name"] )
208
- end
209
- }
210
- end
211
- end
212
- end
6
+ require 'jiji/agent/util'
7
+ require 'jiji/util/file_lock'
8
+ require 'set'
9
+ require "thread"
10
+
11
+ module JIJI
12
+
13
+ # プロセス
14
+ class Process
15
+
16
+ # コンストラクタ
17
+ def initialize( info )
18
+ @info = info
19
+ @started_mutex = Mutex.new
20
+ @started_mutex.synchronize {
21
+ @started= false
22
+ }
23
+ end
24
+
25
+ #エージェントをロードする
26
+ def load_agents( ignore_error )
27
+ info.load_agents( agent_manager,
28
+ agent_manager.agent_registry, logger, ignore_error )
29
+ end
30
+
31
+ def start
32
+ @started_mutex.synchronize {
33
+ @started= true
34
+ collector.listeners << self
35
+ collector.start
36
+ }
37
+ # 状態を覚えておく
38
+ info["state"] = collector.state
39
+ end
40
+
41
+ def stop
42
+ @started_mutex.synchronize {
43
+ if @started # 起動していない場合は何もしない
44
+ observer_manager.stop
45
+ collector.stop
46
+
47
+ # 状態を覚えておく
48
+ info["state"] = collector.state
49
+ @started = false
50
+ else
51
+ # 待機中の場合、キャンセル状態にする。
52
+ if info["state"] == :WAITING
53
+ info["state"] = :CANCELED
54
+ end
55
+ logger.close if logger
56
+ @logger = nil
57
+ end
58
+ }
59
+ end
60
+
61
+ #自動取引のon/offを設定する
62
+ def trade_enable=(enable)
63
+ agent_manager.operator.trade_enable = enable
64
+ end
65
+
66
+ #エージェントの設定を更新する
67
+ #戻り値:: 変更に失敗したエージェントの一覧
68
+ def set_agents(agents)
69
+ failed = {}
70
+ # エージェントの設定が更新された
71
+ # 削除対象を特定するため、登録済みエージェントのIDのセットを作成
72
+ set = info["agents"] ? info["agents"].inject({}){|s,i| s[i["id"]]=i;s} : {}
73
+ agents.each {|item|
74
+ # プロパティの更新 / 対応するエージェントが存在しなければ作成。
75
+ set_agent_properties( item, agent_manager, failed )
76
+ set.delete item["id"]
77
+ }
78
+ # Mapに含まれていないエージェントは削除
79
+ set.each { |pair|
80
+ info = pair[1]
81
+ begin
82
+ logger.info "remove agent. name=#{info["name"]} id=#{info["id"]}"
83
+ agent_manager.remove( info["id"] )
84
+ rescue Exception
85
+ logger.warn "failed to remove agent. name=#{info["name"]} id=#{info["id"]}"
86
+ logger.warn $!
87
+ failed[info["id"]] = {:cause=>$!.to_s,:info=>info,:operation=>:remove}
88
+ end
89
+ }
90
+ failed
91
+ end
92
+
93
+ # コレクターの終了通知を受け取る
94
+ def on_finished( state, now )
95
+ begin
96
+ info["state"] = state
97
+ agent_manager.flush( now )
98
+ ensure
99
+ logger.close if logger
100
+ @logger = nil
101
+ end
102
+ end
103
+
104
+ # コレクターからの進捗通知を受け取る
105
+ def on_progress_changed( progress )
106
+ info.progress = progress
107
+ end
108
+
109
+ attr :info, true
110
+ attr :collector, true
111
+ attr :observer_manager, true
112
+ attr :agent_manager, true
113
+ attr :logger, true
114
+
115
+ private
116
+ # 任意のエージェントの設定を更新する。
117
+ # エージェントは初期化されない。propertiesのみ変更される。
118
+ def set_agent_properties( item, agent_manager, failed )
119
+ id, name, props, cl = item["id"], item["name"], item["properties"], item["class"]
120
+ a = agent_manager.get(id)
121
+ begin
122
+ if a
123
+ logger.info "update agent. name=#{name} id=#{id}"
124
+ a.agent.properties = props
125
+ if name
126
+ a.output.agent_name = name
127
+ a.operator.agent_name = name
128
+ end
129
+ else
130
+ logger.info "add agent. name=#{name} id=#{id}"
131
+ agent = agent_manager.agent_registry.create( cl, props )
132
+ agent_manager.add( id, agent, name )
133
+ end
134
+ rescue Exception
135
+ logger.warn " failed to create or update agent. name=#{name} id=#{id}"
136
+ logger.warn $!
137
+ failed[id] = {:cause=>$!.to_s,:info=>item, :operation=> a ? :update : :add}
138
+ end
139
+ end
140
+ end
141
+
142
+ # プロセス情報
143
+ class ProcessInfo
144
+
145
+ PROPERTY_FILE = "props.yaml"
146
+
147
+ # コンストラクタ
148
+ def initialize( process_id, process_dir )
149
+ @process_id = process_id
150
+ @process_dir = process_dir
151
+ FileUtils.mkdir_p dir
152
+ @progress = 0
153
+ @props = {}
154
+ end
155
+
156
+ #データが存在するか評価する
157
+ def data_exist?
158
+ File.exist? prop_file
159
+ end
160
+
161
+ # 設定を保存する
162
+ def save
163
+ file = prop_file
164
+ lock {
165
+ File.open( file, "w" ) { |f|
166
+ f.write( YAML.dump(@props) )
167
+ }
168
+ }
169
+ end
170
+
171
+ # 設定をロードする
172
+ def load
173
+ # 保存したファイルがあれば、ファイルから設定値を読み込む
174
+ file = prop_file
175
+ lock {
176
+ if ( File.exist? file )
177
+ @props = YAML.load_file file
178
+ end
179
+ }
180
+ end
181
+
182
+ def []=(k,v)
183
+ @props[k] = v
184
+ save
185
+ end
186
+ def [](k)
187
+ @props[k]
188
+ end
189
+ def props=(props)
190
+ @props = props
191
+ save
192
+ end
193
+
194
+ #設定情報を元にエージェントを作成し、agent_managerに登録する
195
+ #agent_manager:: エージェントマネージャ
196
+ #agent_registry:: エージェントレジストリ
197
+ #logger:: エージェントのロードでエラーになった場合のログの出力先
198
+ #ignore_error:: ロードエラーを例外として通知するかどうか。通知しない場合true
199
+ def load_agents( agent_manager, agent_registry, logger, ignore_error=false )
200
+ agent_manager.clear
201
+ return if !@props || !@props.key?("agents")
202
+ @props["agents"].each {|v|
203
+ begin
204
+ agent = agent_registry.create( v["class"], v["properties"] )
205
+ agent_manager.add( v["id"], agent, v["name"] )
206
+ rescue Exception
207
+ logger.warn " failed to create agent. name=#{v["name"]} id=#{v["id"]}"
208
+ logger.warn $!
209
+ raise $! unless ignore_error
210
+ end
211
+ }
212
+ end
213
+
214
+ #ID
215
+ attr :process_id, true
216
+ #プロパティ
217
+ attr_reader :props
218
+ #進捗状況
219
+ attr :progress, true
220
+
221
+ private
222
+ def prop_file
223
+ "#{dir}/#{PROPERTY_FILE}"
224
+ end
225
+ def dir
226
+ "#{@process_dir}/#{@process_id}"
227
+ end
228
+ def lock
229
+ DirLock.new( dir ).writelock {
230
+ yield
231
+ }
232
+ end
233
+ end
213
234
  end