dango 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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