dango 0.1.0 → 0.2.2

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.
@@ -31,7 +31,8 @@ module DangoFrameworkModule
31
31
  raise(DangoFrameworkError, "Shared key is not exist.")
32
32
  end
33
33
  @mutex[key].synchronize do
34
- data = yield(@data[key].deep_dup)
34
+ # data = yield(@data[key].deep_dup)
35
+ data = yield(@data[key])
35
36
  @data[key] = data.deep_dup
36
37
  end
37
38
  end
@@ -2,73 +2,202 @@
2
2
  ENV['RAILS_ENV'] = ENV['RAILS_ENV'] || 'development'
3
3
 
4
4
  require "pp"
5
+ require "timeout"
5
6
 
6
- namespace :dango do
7
- desc "initialize dango"
8
- task :initialize do
9
- puts "complete initialize."
10
- end
11
7
 
12
- desc "make swf"
13
- task :make_swf do
14
- puts "complete make_swf."
15
- end
8
+ # verboseモードのフラグを立てる処理
9
+ def check_verbose_mode()
10
+ $is_verbose = (ENV["verbose"] == "true" || ENV["verbose"] == "on") ? true : false
11
+ end
16
12
 
17
- desc "check dango process"
18
- task :check_dango_process do
19
- # pidのチェック
13
+ # pid保存ファイルの読み出し
14
+ def get_dango_pid()
15
+ begin
20
16
  pid = open("tmp/pids/dango.pid", "rb"){|fh| fh.read }.to_i
21
- puts "pid=#{pid}"
17
+ rescue
18
+ pid = nil
19
+ end
20
+ puts "pid=#{pid.inspect}" if $is_verbose
21
+ pid
22
+ end
23
+
24
+ # pidのプロセスがあるかどうかのチェック
25
+ def check_exist_dango_process(pid)
26
+ puts "check_exist_dango_process(pid=#{pid})" if $is_verbose
27
+
28
+ # そのpidのプロセスがあるかのチェック
29
+ is_pid_exist = nil
30
+
31
+ if RUBY_PLATFORM == 'i386-mswin32'
32
+ # WbemからProcessIDを取得
33
+ require "win32ole"
34
+ begin
35
+ n_locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
36
+ n_service = n_locator.ConnectServer
37
+ rescue
38
+ puts "failed connect to Wbem:#{$!.inspect}" if $is_verbose
39
+ return
40
+ end
22
41
 
23
- # そのpidのプロセスがあるかのチェック
24
- is_pid_exist = nil
25
- if RUBY_PLATFORM == 'i386-mswin32'
26
- # WbemからProcessIDを取得
27
- require "win32ole"
28
- begin
29
- n_locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
30
- n_service = n_locator.ConnectServer
31
- rescue
32
- puts "failed connect to Wbem:#{$!.inspect}"
33
- return
42
+ set = n_service.ExecQuery("select Caption, ProcessID from Win32_Process where ProcessID = #{pid}")
43
+ set.each do |one|
44
+ # puts(sprintf("Win32_Process %8d %s", one.ProcessID, one.Caption))
45
+ if one.ProcessID == pid
46
+ is_pid_exist = true
34
47
  end
48
+ end
49
+
50
+ else ## i386-mswin32以外
51
+ is_pid_exist = FileTest.exist?("/proc/#{pid}")
52
+ end
53
+
54
+ if is_pid_exist
55
+ puts "dango_process is exist." if $is_verbose
56
+ else
57
+ puts "dango_process is not exist." if $is_verbose
58
+ end
59
+
60
+ is_pid_exist
61
+ end
62
+
63
+ # プロセス停止
64
+ def stop_process(pid)
65
+ puts "stop process (pid=#{pid})" if $is_verbose
66
+
67
+ if RUBY_PLATFORM == 'i386-mswin32'
68
+ # WbemからProcessIDを取得
69
+ require "win32ole"
70
+ begin
71
+ n_locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
72
+ n_service = n_locator.ConnectServer
73
+ rescue
74
+ puts "failed connect to Wbem:#{$!.inspect}" if $is_verbose
75
+ return
76
+ end
77
+
78
+ set = n_service.ExecQuery("select Caption, name, ProcessID from Win32_Process where ProcessID = '#{pid}'")
79
+ set.each do |process|
80
+ puts "stopping #{process.Caption} #{process.name} #{process.ProcessID}" if $is_verbose
81
+ process.Terminate 0
82
+ end
83
+
84
+ else ## i386-mswin32以外
85
+ system("kill -9 #{pid}")
86
+ end
87
+ end
88
+
89
+ # サーバーへの通信を使ったチェック
90
+ def check_dango_connect()
91
+ require 'dango/tester/dango_tester_client'
92
+
93
+ # コンフィグから check_dango_process_cmd を取得
94
+ config = YAML.load(open("dango/config/#{ENV['RAILS_ENV']}.yml", "rb"){|fh| fh.read})
95
+
96
+ serv_info = {}
97
+ serv_info["host"] = config['network']['host'] || 'localhost'
98
+ serv_info["port"] = config['network']['port'] || 15000
99
+ # pp serv_info
100
+
101
+ tester = DangoTesterClient.new # 開始
102
+
103
+ begin
104
+ tester1 = nil
105
+ sid = nil
106
+ timeout(8) do
107
+ tester1 = tester.new_client("tester1", serv_info) # テスター1
35
108
 
36
- set = n_service.ExecQuery("select Caption, ProcessID from Win32_Process")
37
- set.each do |one|
38
- # puts(sprintf("Win32_Process %8d %s", one.ProcessID, one.Caption))
39
- if one.ProcessID == pid
40
- is_pid_exist = true
41
- end
109
+ sleep 3
110
+ loop do
111
+ sid = tester1.sid
112
+ break if sid
113
+ sleep 1
42
114
  end
43
- else
44
- is_pid_exist = FileTest.exist?("/proc/#{pid}")
45
115
  end
116
+ rescue TimeoutError
117
+ sid = nil
118
+ ensure
119
+ tester1.dango_client_close if tester1.respond_to?(:dango_client_close)
120
+ tester1 = nil
121
+ tester.gc_thread_stop
122
+ end
123
+
124
+ puts "sid=#{sid.inspect}" if $is_verbose
125
+
126
+ if sid
127
+ is_alive_server = true
128
+ else
129
+ is_alive_server = false
130
+ end
131
+
132
+ is_alive_server
133
+ end
134
+
135
+
136
+ namespace :dango do
137
+ # desc "make swf"
138
+ # task :make_swf do
139
+ # puts "complete make_swf." if $is_verbose
140
+ # end
141
+
142
+ desc "stop dango process"
143
+ task :stop_dango_process do
144
+ check_verbose_mode() # verboseモードのフラグを立てる処理
145
+
146
+ pid = get_dango_pid()
147
+ stop_process(pid) if pid # pidがあればプロセス停止
148
+ puts "complete stop dango process." if $is_verbose
149
+ end
150
+
151
+ desc "check dango process"
152
+ task :check_dango_process do
153
+ check_verbose_mode() # verboseモードのフラグを立てる処理
46
154
 
47
- puts "is_pid_exist=#{is_pid_exist}"
155
+ pid = get_dango_pid() # pidのチェック
156
+ is_pid_exist = check_exist_dango_process(pid) # pidのプロセスがあるかどうかのチェック
157
+ is_alive_server = check_dango_connect() if is_pid_exist # サーバーへの通信を使ったチェック
48
158
 
49
159
  # コンフィグから check_dango_process_cmd を取得
50
160
  config = YAML.load(open("dango/config/#{ENV['RAILS_ENV']}.yml", "rb"){|fh| fh.read})
51
161
  check_dango_process_cmd = config['server']['check_dango_process_cmd'] || nil
52
162
 
53
163
  # is_pid_existがないならcheck_dango_process_cmd実行
54
- if ! is_pid_exist && check_dango_process_cmd
55
- puts "check_dango_process_cmd=#{check_dango_process_cmd}"
56
- system(check_dango_process_cmd)
164
+ if check_dango_process_cmd && (! is_alive_server)
165
+ stop_process(pid) if pid # pidがあればプロセス停止
57
166
  end
58
167
 
59
- check_dango_process_cmd
168
+ if check_dango_process_cmd && ((! is_pid_exist) || (! is_alive_server))
169
+ puts "check_dango_process_cmd=#{check_dango_process_cmd}" if $is_verbose
170
+ system(check_dango_process_cmd)
171
+ end
60
172
 
61
- puts "complete check_dango_process."
173
+ puts "complete check_dango_process." if $is_verbose
62
174
  end
63
175
 
64
176
  namespace :monitor do
65
177
  desc "get server info"
66
178
  task :get_server_info do
67
- puts "get server info"
179
+ check_verbose_mode() # verboseモードのフラグを立てる処理
180
+
181
+ puts "server_reload"
182
+ require 'dango/monitor/dango_monitor_client.rb'
183
+ begin
184
+ dm = DangoMonitorClient.new()
185
+ pp dm.get_server_info()
186
+ dm.dango_client_close
187
+ puts "complete get_server_info."
188
+ rescue
189
+ pp $!.class
190
+ pp $!.message
191
+ pp $!.backtrace
192
+ puts "failed get_server_info."
193
+ end
194
+
68
195
  end
69
196
 
70
197
  desc "server_reload" # サーバーのリロード処理
71
198
  task :server_reload do
199
+ check_verbose_mode() # verboseモードのフラグを立てる処理
200
+
72
201
  puts "server_reload"
73
202
  require 'dango/monitor/dango_monitor_client.rb'
74
203
  begin
@@ -86,7 +215,9 @@ namespace :dango do
86
215
 
87
216
  desc "send_system_message" # システムメッセージ配信
88
217
  task :send_system_message do
89
- puts "send_system_message"
218
+ check_verbose_mode() # verboseモードのフラグを立てる処理
219
+
220
+ puts "send_system_message" if $is_verbose
90
221
  message_type = ENV["TYPE"]
91
222
  if ! message_type
92
223
  puts "please type. ex. rake dango:monitor:send_system_message TYPE=down_1min"
@@ -14,7 +14,9 @@ class DangoTesterClient
14
14
  GCIntervalSec = 5.0 # GCの発生タイミング
15
15
 
16
16
  # テスターのイニシャライズ
17
- def initialize
17
+ def initialize(debug = false)
18
+ @debug = debug
19
+
18
20
  @client_conns = {}
19
21
  Thread.abort_on_exception = true
20
22
 
@@ -32,7 +34,7 @@ class DangoTesterClient
32
34
  "port"=>serv_info["port"],
33
35
  },
34
36
  }
35
- env = "development"
37
+ env = ENV['RAILS_ENV'] || 'development'
36
38
 
37
39
  # 接続
38
40
  client_conn = nil
@@ -43,7 +45,7 @@ class DangoTesterClient
43
45
  rescue
44
46
  client_conn = nil
45
47
  raise("connection error for retry times over.") if i == ConnectionRetryTimes - 1
46
- puts "connection failed. sleep #{ConnectionRetryIntervalSec}"
48
+ puts "connection failed. sleep #{ConnectionRetryIntervalSec}" if @debug
47
49
  sleep ConnectionRetryIntervalSec
48
50
  end
49
51
  end
@@ -74,7 +76,7 @@ class DangoTesterClient
74
76
 
75
77
  # GCスレッドの開始
76
78
  def gc_thread_start
77
- th = Thread.start do
79
+ gc_thread = Thread.start do
78
80
  loop do
79
81
  begin
80
82
  sleep @gc_interval_sec
@@ -83,21 +85,28 @@ class DangoTesterClient
83
85
  GC.enable
84
86
  GC.start
85
87
  GC.disable
86
- puts "GC #{Time.now - gc_start_time}sec #{Time.now_to_s}"
88
+ puts "GC #{Time.now - gc_start_time}sec #{Time.now_to_s}" if @debug
87
89
 
88
90
  rescue
89
91
  puts "Exception gc_thread_start #{Time.now_to_s} #{error_message($!, 'u')}"
90
92
  end
91
93
  end
92
94
  end
93
- th.priority = -1
95
+ gc_thread.priority = -1
96
+
97
+ @gc_thread = gc_thread
98
+ end
99
+
100
+ # GCスレッドの終了
101
+ def gc_thread_stop
102
+ @gc_thread.kill
94
103
  end
95
104
 
96
105
  end
97
106
 
98
107
  # テスト接続用のクラス
99
108
  class TestClient < DangoClientFramework
100
- SendReceiveSleepIntervalSec = 0.03 # データ送信後の順の際のタイムアウトチェック間隔秒
109
+ SendReceiveSleepIntervalSec = 0.1 # データ送信後の順の際のタイムアウトチェック間隔秒
101
110
  ReceiveWaitTimeoutSec = 10 # データ受信確認の待ち秒数
102
111
  ReceiveTrapTimeoutSec = 0 # データ受信確認のトラップの秒数
103
112
 
@@ -107,13 +116,15 @@ class TestClient < DangoClientFramework
107
116
 
108
117
  super(env, config)
109
118
 
110
- @receive_mutex = Mutex.new # 送受信用の排他処理
111
- @receive_arr = []
112
- @trap_thread_hash = {}
119
+ send_receive_shared_init()
113
120
 
114
- @receive_methods = []
121
+ # @receive_mutex = Mutex.new # 受信用の排他処理
122
+ # @receive_arr = []
123
+ # @trap_thread_hash = {}
124
+ # @receive_methods = []
125
+
126
+ send_receive_shared[:receive_cache] = [] # 受信データ用のキャッシュ初期化
115
127
 
116
- send_receive_shared_init()
117
128
  end
118
129
 
119
130
  attr_accessor(:client_name)
@@ -137,10 +148,33 @@ class TestClient < DangoClientFramework
137
148
 
138
149
  # テストサーバー
139
150
  def send(name, send_obj = {})
140
- logger.debug("tester.send:send_obj=#{send_obj.inspect} ")
151
+ logger.debug("tester.send:name=#{name}:send_obj=#{send_obj.inspect} ")
141
152
  send_action(name, send_obj)
142
153
  end
143
154
 
155
+ # データ受信時の処理をするためにmethod_missingを定義
156
+ def method_missing(name, *args)
157
+ if name.to_s =~ /^dango_receive_/ && args.length == 1
158
+ ret_obj = args[0]
159
+ logger.debug "ret_obj:#{name}:" + ret_obj.inspect + " " + Time.now_to_s
160
+ send_receive_shared.transaction(:receive_cache) do |receive_cache|
161
+ receive_cache.push([name, ret_obj, Time.now])
162
+ receive_cache
163
+ end
164
+
165
+ else
166
+ logger.info "method not found. #{name.inspect} #{args.inspect}"
167
+ raise(NameError, "method not found. #{name.inspect} #{args.inspect}")
168
+ end
169
+ end
170
+
171
+ # send_receive_shared[:receive_cache]の中身を返すメソッド
172
+ def get_receive_cache
173
+ send_receive_shared[:receive_cache]
174
+ end
175
+
176
+
177
+ =begin
144
178
  # trap_receive
145
179
  def trap_receive(notice_name, options = {})
146
180
  logger.debug "trap_receive_data:#{notice_name}:"
@@ -231,6 +265,7 @@ class TestClient < DangoClientFramework
231
265
  logger.debug "trap_receive_data:already register trap:notice_name:#{notice_name} "
232
266
  end
233
267
 
268
+ logger.debug "trap_receive_data:registered:#{notice_name}:"
234
269
  end
235
270
 
236
271
  # cancel trap_receive
@@ -255,8 +290,51 @@ class TestClient < DangoClientFramework
255
290
  @receive_arr.delete_if{|r| r[0] == notice_name}
256
291
  end
257
292
  end
293
+ =end
258
294
 
259
295
  # wait_receive
296
+ def wait_receive(notice_name, options = {})
297
+ logger.debug "wait_receive_data:#{notice_name}:"
298
+ timeout = options[:timeout] || ReceiveWaitTimeoutSec
299
+
300
+ # データ受信待ち
301
+ receive_data = nil
302
+ receive_idx = nil
303
+
304
+ end_reserved_time = Time.now + timeout # 0以上ならタイムアウト時間決定
305
+
306
+ loop do
307
+ logger.debug "wait_receive_data:loop:#{send_receive_shared[:receive_cache].inspect}"
308
+
309
+ send_receive_shared[:receive_cache].each_with_index do |rec_data, i|
310
+ if rec_data[0].to_s == "dango_receive_" + notice_name.to_s
311
+ receive_data = rec_data.deep_dup
312
+ receive_idx = i
313
+ break
314
+ end
315
+ end
316
+
317
+ break if receive_data != nil
318
+ break if end_reserved_time < Time.now
319
+
320
+ sleep SendReceiveSleepIntervalSec # スリープ
321
+ end
322
+
323
+ # タイムアウトなら
324
+ if receive_data == nil
325
+ raise(DangoFrameworkTimeoutError, "timeout:timeout_sec=#{timeout}: \n client_name=#{@client_name}(#{self.sid}) \n :notice_name=#{notice_name} \n")
326
+ end
327
+
328
+ # 結果を削除しておく
329
+ send_receive_shared.transaction(:receive_cache) do |receive_cache|
330
+ receive_cache.delete_at(receive_idx)
331
+ receive_cache
332
+ end
333
+
334
+ receive_data[1]
335
+ end
336
+
337
+ =begin
260
338
  def wait_receive(notice_name, options = {})
261
339
  logger.debug "wait_receive_data:#{notice_name}:"
262
340
  timeout = options[:timeout] || ReceiveWaitTimeoutSec
@@ -300,6 +378,7 @@ class TestClient < DangoClientFramework
300
378
  end
301
379
  receive_arr
302
380
  end
381
+ =end
303
382
 
304
383
  end
305
384