dango 0.4.8 → 0.5.0
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.
- data/lib/dango/client_framework.rb +13 -12
- data/lib/dango/controller_plugin/dango_controller_plugin.rb +7 -3
- data/lib/dango/dango_g_server.rb +7 -6
- data/lib/dango/dango_logger.rb +115 -0
- data/lib/dango/dango_mutex.rb +64 -0
- data/lib/dango/default_dango_receive.rb +140 -0
- data/lib/dango/error_message.rb +30 -0
- data/lib/dango/framework_base.rb +112 -79
- data/lib/dango/monitor/server_monitor_module.rb +131 -0
- data/lib/dango/server_framework.rb +215 -145
- data/lib/dango/session_manager.rb +15 -10
- data/lib/dango/shared/memory_store.rb +10 -10
- data/lib/dango/socket_list.rb +5 -5
- data/lib/dango/tasks/dango_rake.rb +379 -166
- data/lib/dango/tester/dango_tester_client.rb +1 -6
- data/lib/dango/version.rb +2 -2
- metadata +8 -3
@@ -10,11 +10,15 @@ require "dango/framework_base"
|
|
10
10
|
require "dango/socket_list"
|
11
11
|
require "dango/version"
|
12
12
|
require "dango/session_manager"
|
13
|
-
require "dango/monitor/server_monitor_action"
|
13
|
+
#require "dango/monitor/server_monitor_action"
|
14
|
+
require "dango/monitor/server_monitor_module"
|
15
|
+
require "dango/default_dango_receive"
|
14
16
|
|
15
17
|
# フレームワーククラス
|
16
18
|
class DangoServerFramework
|
17
19
|
require "dango/dango_g_server"
|
20
|
+
include DefaultDangoReceive
|
21
|
+
include ServerMonitorModule
|
18
22
|
|
19
23
|
include DangoFrameworkModule
|
20
24
|
|
@@ -107,14 +111,15 @@ class DangoServerFramework
|
|
107
111
|
|
108
112
|
# スレッドグループの初期化
|
109
113
|
@thr_gr_gserver_serve = ThreadGroup.new
|
110
|
-
@thr_gr_send_notice = ThreadGroup.new
|
111
|
-
@thr_gr_send_data = ThreadGroup.new
|
112
114
|
|
113
115
|
# データ送信用スレッドとQueue
|
114
116
|
@queue_send_notice = Queue.new
|
115
|
-
@mutex_send_notice =
|
117
|
+
@mutex_send_notice = DangoMutex.new(:mutex_send_notice)
|
116
118
|
Thread.start{ thread_send_notice_queue() }
|
117
119
|
|
120
|
+
# メインスレッドの名前
|
121
|
+
Thread.current[:_name] = "main"
|
122
|
+
|
118
123
|
# サーバー開始
|
119
124
|
server_start()
|
120
125
|
|
@@ -146,31 +151,42 @@ class DangoServerFramework
|
|
146
151
|
logger.warn("max_connections=#{@server_max_connections}")
|
147
152
|
logger.warn("RAILS_ENV=#{RAILS_ENV}")
|
148
153
|
logger.warn("Process.pid=#{Process.pid}")
|
149
|
-
logger.warn("Dango Version=#{Dango::VERSION::STRING}")
|
150
|
-
#
|
154
|
+
logger.warn("Dango Version=#{Dango::VERSION::STRING} p11")
|
155
|
+
# logger.debug("$LOADED_FEATURES=#{$LOADED_FEATURES.pretty_inspect}")
|
151
156
|
|
152
157
|
shared_init() # 共有メモリを初期化
|
153
158
|
socket_list_init() # ソケット一覧を初期化
|
154
159
|
@mutex_sock = {} # ソケットの排他処理ハッシュ
|
155
160
|
@session_manager = SessionManager.new(shared, RAILS_ENV) # セッション情報の初期化
|
156
161
|
|
157
|
-
@mutex_proc_thread =
|
162
|
+
@mutex_proc_thread = DangoMutex.new(:mutex_proc_thread) # スレッドが同時起動しないようにするためのMutex
|
158
163
|
heart_beat_thread_start() # ハートビートスレッドの開始
|
159
164
|
gc_thread_start() # GCスレッドの開始
|
160
165
|
|
161
166
|
dango_server_init() # 初期設定読み込み
|
162
167
|
|
163
|
-
@mutex_send_response =
|
164
|
-
@arr_send_response = []
|
168
|
+
@mutex_send_response = DangoMutex.new(:mutex_send_response) # 送信レスポンス用のMutex
|
169
|
+
@arr_send_response = [] # 送信レスポンス用のキャッシュ
|
165
170
|
|
166
171
|
|
167
172
|
TCPSocket.do_not_reverse_lookup = true # 逆引きを行わない
|
168
173
|
# TCPSocket.do_not_reverse_lookup = false # 逆引きを行う
|
169
174
|
|
170
175
|
if @backdoor_run_drb_server # backdoor用のdrbを起動
|
171
|
-
|
172
|
-
|
173
|
-
|
176
|
+
require "drb"
|
177
|
+
require "drb/acl"
|
178
|
+
# uri = "druby://#{@network_host}:#{@backdoor_run_drb_port}"
|
179
|
+
uri = @backdoor_run_drb_url
|
180
|
+
list = ["deny", "all", "allow", @backdoor_host]
|
181
|
+
acl = ACL.new(list, ACL::DENY_ALLOW)
|
182
|
+
@drb = DRb.start_service(uri, self, acl)
|
183
|
+
# @drb = DRb.start_service(uri, self)
|
184
|
+
DRb.thread[:_name] = "thread_drb_main"
|
185
|
+
message = "start drb server: uri=#{DRb.uri}"
|
186
|
+
logger.warn(message)
|
187
|
+
puts message
|
188
|
+
else
|
189
|
+
@drb = nil
|
174
190
|
end
|
175
191
|
|
176
192
|
set_loop_setting(@loop_setting) if @loop_setting # ループ処理を定義
|
@@ -193,9 +209,9 @@ class DangoServerFramework
|
|
193
209
|
@gserver.start(@server_max_connections, 20) # backlogを20に設定
|
194
210
|
|
195
211
|
rescue Exception
|
196
|
-
puts error_message($!)
|
212
|
+
puts "gserver.start:" + error_message($!)
|
197
213
|
# error_print(error_message($!, 'u'))
|
198
|
-
exit
|
214
|
+
exit!
|
199
215
|
end
|
200
216
|
end
|
201
217
|
|
@@ -207,9 +223,14 @@ class DangoServerFramework
|
|
207
223
|
|
208
224
|
debug_print("-- stopping server")
|
209
225
|
stop_gserver() # gserverの停止
|
210
|
-
|
211
226
|
@gserver = nil
|
212
227
|
|
228
|
+
if @drb # drbを起動していればそれの停止
|
229
|
+
DRb.stop_service()
|
230
|
+
puts "stop drb server"
|
231
|
+
@drb = nil
|
232
|
+
end
|
233
|
+
|
213
234
|
debug_print("-- stopped server")
|
214
235
|
|
215
236
|
# GCを行う
|
@@ -221,14 +242,14 @@ class DangoServerFramework
|
|
221
242
|
debug_print("-- reload classes")
|
222
243
|
tmp_verbose = $VERBOSE
|
223
244
|
$VERBOSE = nil
|
224
|
-
|
245
|
+
|
225
246
|
# serverファイル名一覧を取得
|
226
247
|
load_files = []
|
227
248
|
glob_str = 'dango/server/*.rb'
|
228
249
|
Dir.glob(glob_str) do |srv_file|
|
229
250
|
load_files.push({:file=>srv_file, :mtime=>File.mtime(srv_file)})
|
230
251
|
end
|
231
|
-
|
252
|
+
|
232
253
|
# ファイル名順にソート
|
233
254
|
load_files = load_files.sort_by{|f| f[:file] }
|
234
255
|
load_files.each do |f|
|
@@ -238,7 +259,7 @@ class DangoServerFramework
|
|
238
259
|
debug_print("#{error_message($!, 'u')}")
|
239
260
|
end
|
240
261
|
end
|
241
|
-
|
262
|
+
|
242
263
|
$VERBOSE = tmp_verbose
|
243
264
|
|
244
265
|
# サーバーを再度起動
|
@@ -252,7 +273,7 @@ class DangoServerFramework
|
|
252
273
|
|
253
274
|
# gserver接続開始処理
|
254
275
|
def connecting(sock)
|
255
|
-
logger.info "connecting:sock=#{sock} peeraddr=#{sock.peeraddr.inspect} addr=#{sock.addr.inspect}"
|
276
|
+
logger.info "connecting:sock=#{sock.object_id} peeraddr=#{sock.peeraddr.inspect} addr=#{sock.addr.inspect}"
|
256
277
|
end
|
257
278
|
|
258
279
|
# gserver接続開始処理
|
@@ -276,7 +297,8 @@ class DangoServerFramework
|
|
276
297
|
|
277
298
|
# gserverのserveメソッド:スレッド開始処理
|
278
299
|
def thread_main(sock)
|
279
|
-
logger.info "thread_main:connect. sock=#{sock} thread.current=#{Thread.current.object_id}"
|
300
|
+
logger.info "thread_main:connect. sock=#{sock.object_id} thread.current=#{Thread.current.object_id}"
|
301
|
+
Thread.current[:_name] = "thread_main #{sock.object_id}"
|
280
302
|
|
281
303
|
@thr_gr_gserver_serve.add(Thread.current) # スレッドグループに登録
|
282
304
|
|
@@ -285,9 +307,9 @@ class DangoServerFramework
|
|
285
307
|
sid = session[:sid]
|
286
308
|
|
287
309
|
# sockに対しての=nil write close などの書き換えに対する排他処理
|
288
|
-
@mutex_sock[sock.object_id] =
|
310
|
+
@mutex_sock[sock.object_id] = DangoMutex.new("mutex_sock_#{sock.object_id}")
|
289
311
|
|
290
|
-
@mutex_sock[sock.object_id].
|
312
|
+
@mutex_sock[sock.object_id].timeout_sync(2, "start #{sock.object_id}") do
|
291
313
|
sock.binmode
|
292
314
|
sock.sync = true
|
293
315
|
|
@@ -298,7 +320,7 @@ class DangoServerFramework
|
|
298
320
|
|
299
321
|
session[:encode_type] = DefaultEncodeType
|
300
322
|
|
301
|
-
logger.debug "thread_main:start_session. sid=#{sid} sock=#{sock} thread.current=#{Thread.current.object_id}"
|
323
|
+
logger.debug "thread_main:start_session. sid=#{sid} sock=#{sock.object_id} thread.current=#{Thread.current.object_id}"
|
302
324
|
|
303
325
|
socket_list.add(sid, sock)
|
304
326
|
|
@@ -306,28 +328,32 @@ class DangoServerFramework
|
|
306
328
|
|
307
329
|
is_flash_policy_file = false
|
308
330
|
|
309
|
-
# 誰かが接続したときに60秒以上経った@arr_send_responseを削除
|
310
|
-
@mutex_send_response.synchronize do
|
311
|
-
@arr_send_response.delete_if{|r| r[:time] < Time.now - 60}
|
312
|
-
end
|
313
|
-
|
314
331
|
logger.debug "thread_main:do main loop."
|
315
332
|
|
316
333
|
# メインループ入り
|
334
|
+
count = 0
|
317
335
|
loop do
|
318
336
|
if sock.closed?
|
319
|
-
logger.info "#{sock.
|
337
|
+
logger.info "#{sock.object_id}:sock is closed... #{count}"
|
320
338
|
break
|
321
339
|
end
|
322
340
|
|
323
341
|
ret_objs = nil
|
324
342
|
begin
|
343
|
+
logger.debug "dango_receive_data:start:sock=#{sock.object_id} #{count}" if count % 100 == 0
|
325
344
|
ret_objs = dango_receive_data(sock) # データ受信処理
|
345
|
+
logger.debug "dango_receive_data:finish:sock=#{sock.object_id} #{count}" if count % 100 == 0
|
326
346
|
is_flash_policy_file = false
|
327
347
|
rescue DangoFrameworkFlashPolicyException
|
328
348
|
is_flash_policy_file = true
|
329
349
|
end
|
330
350
|
|
351
|
+
# メンテナンス機能
|
352
|
+
if shared[:_is_server_sleep]
|
353
|
+
logger.info "thread_main SLEEP !!!"
|
354
|
+
sleep 10000
|
355
|
+
end
|
356
|
+
|
331
357
|
if is_flash_policy_file # Flashのポリシーファイルが来たら
|
332
358
|
logger.debug "is_flash_policy_file"
|
333
359
|
do_flash_policy_file(sid, sock)
|
@@ -340,6 +366,8 @@ class DangoServerFramework
|
|
340
366
|
logger.debug "ret_objs is empty. "
|
341
367
|
|
342
368
|
else # 受信データがあれば
|
369
|
+
logger.debug "dango_receive_data:ret_objs=#{ret_objs.class} #{count}" if count % 100 == 0
|
370
|
+
|
343
371
|
ret_objs.each do |ret_obj| # 受信データループ
|
344
372
|
if !(ret_obj && ret_obj["_action_name"]) # action_nameが無い場合はエラー
|
345
373
|
logger.warn "no action_name error:#{ret_obj.inspect}"
|
@@ -351,37 +379,27 @@ class DangoServerFramework
|
|
351
379
|
session[:_action_name] = action_name
|
352
380
|
|
353
381
|
# 自動返信用データ
|
354
|
-
|
382
|
+
return_data = {}
|
355
383
|
ret_obj.each do |key, value|
|
356
384
|
if key =~ /^_return_(.*)$/
|
357
|
-
|
385
|
+
return_data[$1.to_sym] = value
|
358
386
|
end
|
359
387
|
end
|
388
|
+
session[:_return] = return_data
|
360
389
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
elsif action_name == '_change_encode_type' # エンコードタイプの変更なら
|
372
|
-
action_name_is_change_encode_type(ret_obj)
|
373
|
-
|
374
|
-
else # メンテナンスコマンド以外のユーザーアクション名なら
|
375
|
-
logger.debug "receive_action:#{sid}:#{action_name}:"
|
376
|
-
begin
|
377
|
-
__send__("dango_receive_#{action_name}", ret_obj)
|
378
|
-
rescue NoMethodError
|
379
|
-
@recv_fail_count += 1 if @recv_fail_count # 受信失敗回数カウント
|
380
|
-
logger.error "not find action #{action_name}:#{sid}:#{error_message($!, 'u')}"
|
381
|
-
end
|
390
|
+
logger.debug "mpth:1:receive_action:session=#{sid} #{count}"
|
391
|
+
@mutex_proc_thread.timeout_sync(4, "receive_action_#{action_name}") do
|
392
|
+
logger.debug "mpth:2:receive_action:#{sid}:#{action_name}:"
|
393
|
+
begin
|
394
|
+
__send__("dango_receive_#{action_name}", ret_obj)
|
395
|
+
rescue NoMethodError
|
396
|
+
@recv_fail_count += 1 if @recv_fail_count # 受信失敗回数カウント
|
397
|
+
logger.error "not find action #{action_name}:#{sid}:#{error_message($!, 'u')}"
|
398
|
+
rescue DangoFrameworkTimeoutException
|
399
|
+
logger.error "action is timeout:#{action_name}:#{sid}:#{error_message($!, 'u')}"
|
382
400
|
end
|
383
401
|
|
384
|
-
end # @mutex_proc_thread
|
402
|
+
end # @mutex_proc_thread
|
385
403
|
|
386
404
|
# 不要になったセッション内のデータを削除(sidは再利用されるので消さない)
|
387
405
|
session.delete(:_action_name)
|
@@ -389,7 +407,9 @@ class DangoServerFramework
|
|
389
407
|
end
|
390
408
|
|
391
409
|
if ! session[:connected] # まだdango_connectを呼び出していないなら
|
392
|
-
|
410
|
+
logger.debug "mpth:1:dango_connect"
|
411
|
+
@mutex_proc_thread.timeout_sync(4, :dango_connect) do
|
412
|
+
logger.debug "mpth:2:dango_connect"
|
393
413
|
# 接続直後のsid通知
|
394
414
|
send_obj = {"_sid"=>sid}
|
395
415
|
send_notice("_notice_sid", sid, send_obj)
|
@@ -397,10 +417,12 @@ class DangoServerFramework
|
|
397
417
|
|
398
418
|
dango_connect() # 接続時メソッド呼び出し
|
399
419
|
session[:connected] = true
|
420
|
+
|
400
421
|
end # mutex_proc_thread
|
401
422
|
end
|
402
423
|
end
|
403
424
|
|
425
|
+
count += 1
|
404
426
|
end # loop
|
405
427
|
|
406
428
|
rescue DangoFrameworkFlashPolicyException
|
@@ -424,6 +446,9 @@ class DangoServerFramework
|
|
424
446
|
rescue DangoFrameworkDisconnectException
|
425
447
|
logger.debug "DangoFrameworkDisconnectException. #{sid} \n#{error_message($!, 'u')}"
|
426
448
|
|
449
|
+
rescue DangoFrameworkMutexTimeoutException
|
450
|
+
logger.warn "DangoFrameworkMutexTimeoutException. #{sid} \n#{error_message($!, 'u')}"
|
451
|
+
|
427
452
|
rescue DangoFrameworkException
|
428
453
|
logger.debug "DangoFrameworkException. #{sid} \n#{error_message($!, 'u')}"
|
429
454
|
|
@@ -434,37 +459,62 @@ class DangoServerFramework
|
|
434
459
|
# 接続切断の処理
|
435
460
|
|
436
461
|
if !is_flash_policy_file # Flash Policy Fileなら切断処理不要
|
437
|
-
logger.info "#{sock.
|
462
|
+
logger.info "#{sock.object_id} #{sid} is closing"
|
438
463
|
if session[:connected] # dango_connect()が実行済みなら
|
439
464
|
begin
|
440
|
-
|
465
|
+
logger.debug "mpth:1:dango_close"
|
466
|
+
@mutex_proc_thread.timeout_sync(4, :dango_close) do
|
467
|
+
logger.debug "mpth:2:dango_close"
|
441
468
|
dango_close() # 接続解除時に呼び出されるメソッド
|
469
|
+
|
470
|
+
# ハートビートのごみを削除
|
471
|
+
shared.transaction(:_heart_beat_time_hash) do |hbt_hash|
|
472
|
+
hbt_hash.delete(sid)
|
473
|
+
shared.commit(hbt_hash)
|
474
|
+
end
|
475
|
+
|
442
476
|
end # mutex_proc_thread
|
477
|
+
logger.debug "dango_close end"
|
478
|
+
|
479
|
+
rescue DangoFrameworkMutexTimeoutException
|
480
|
+
logger.warn "DangoFrameworkMutexTimeoutException " +
|
481
|
+
"#{sock.object_id} #{sid} \n#{error_message($!, 'u')}"
|
443
482
|
rescue Exception
|
444
|
-
logger.error "#{sock.
|
483
|
+
logger.error "#{sock.object_id} #{sid} ERROR\n#{error_message($!, 'u')}"
|
445
484
|
end
|
446
485
|
end
|
447
486
|
end
|
448
487
|
|
449
488
|
begin
|
450
|
-
@mutex_sock[sock.object_id].
|
489
|
+
@mutex_sock[sock.object_id].timeout_sync(2, "close #{sock.object_id}") do
|
451
490
|
sock.close # ソケットを閉じる
|
452
491
|
end
|
453
492
|
rescue IOError
|
454
|
-
logger.info "IOError #{sock.
|
493
|
+
logger.info "IOError #{sock.object_id} #{sid}"
|
494
|
+
rescue DangoFrameworkMutexTimeoutException
|
495
|
+
logger.warn "DangoFrameworkMutexTimeoutException #{sock.object_id} #{sid}\n" +
|
496
|
+
"#{error_message($!, 'u')}"
|
455
497
|
rescue Exception
|
456
|
-
logger.error "#{sock.
|
498
|
+
logger.error "#{sock.object_id} #{sid} Exception\n#{error_message($!, 'u')}"
|
457
499
|
end
|
458
500
|
|
459
|
-
logger.info "#{sock.
|
501
|
+
logger.info "#{sock.object_id} #{sid} is closed"
|
460
502
|
|
461
503
|
socket_list.delete(sid) # ソケットリストから削除
|
462
504
|
|
463
|
-
|
464
|
-
|
505
|
+
sock_object_id = sock.object_id
|
506
|
+
begin
|
507
|
+
@mutex_sock[sock_object_id].timeout_sync(2, "delete #{sock.object_id}") do
|
508
|
+
sock = nil # ソケット削除
|
509
|
+
end
|
510
|
+
rescue DangoFrameworkMutexTimeoutException
|
511
|
+
logger.warn "DangoFrameworkMutexTimeoutException #{sock.object_id} #{sid}\n" +
|
512
|
+
"#{error_message($!, 'u')}"
|
513
|
+
rescue Exception
|
514
|
+
logger.error "#{sock.object_id} #{sid} Exception\n#{error_message($!, 'u')}"
|
465
515
|
end
|
466
516
|
|
467
|
-
@mutex_sock.delete(
|
517
|
+
@mutex_sock.delete(sock_object_id) # ソケット排他処理から削除
|
468
518
|
|
469
519
|
@session_manager.close_session(sid) # sessionの終了処理
|
470
520
|
end
|
@@ -492,7 +542,7 @@ class DangoServerFramework
|
|
492
542
|
EOF
|
493
543
|
|
494
544
|
logger.debug policy_data
|
495
|
-
@mutex_sock[sock.object_id].
|
545
|
+
@mutex_sock[sock.object_id].timeout_sync(2, "policy_send #{sock.object_id}") do
|
496
546
|
sock.write policy_data
|
497
547
|
sock.flush
|
498
548
|
end
|
@@ -501,20 +551,6 @@ EOF
|
|
501
551
|
end
|
502
552
|
end
|
503
553
|
|
504
|
-
# action_nameが送信パケットの返事なら
|
505
|
-
def action_name_is_response(ret_obj)
|
506
|
-
logger.debug "action_name_is_response: #{ret_obj['_id'].inspect} #{session[:sid].inspect}"
|
507
|
-
@mutex_send_response.synchronize do
|
508
|
-
@arr_send_response.push({:_id => ret_obj["_id"], :_sid => session[:sid], :time => Time.now})
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
# action_nameが送信パケットの返事なら
|
513
|
-
def action_name_is_change_encode_type(ret_obj)
|
514
|
-
logger.debug "action_name_is_change_encode_type: #{ret_obj['encode_type'].inspect}"
|
515
|
-
session[:encode_type] = ret_obj['encode_type']
|
516
|
-
end
|
517
|
-
|
518
554
|
# 各種サーバー仕様の変数設定
|
519
555
|
def set_server_variables()
|
520
556
|
# 変数の初期設定
|
@@ -552,7 +588,7 @@ EOF
|
|
552
588
|
@statistics_process_memory = @config['server']['statistics_process_memory'] || false # プロセスのメモリ使用量統計取る
|
553
589
|
|
554
590
|
@backdoor_run_drb_server = @config['server']['backdoor_run_drb_server'] || false # drbサーバーを起動するか
|
555
|
-
@
|
591
|
+
@backdoor_run_drb_url = @config['server']['backdoor_run_drb_url'] || 12345 # drbサーバーのポート番号
|
556
592
|
@backdoor_host = @config['server']['backdoor_host'] || '127.0.0.1' # バックドアのアクセス可能ホスト名
|
557
593
|
|
558
594
|
@loop_setting = @config['server']['loop_setting'] # メインループ用の定義
|
@@ -612,6 +648,10 @@ EOF
|
|
612
648
|
@session_manager.session
|
613
649
|
end
|
614
650
|
|
651
|
+
def session_list
|
652
|
+
@session_manager.session_list
|
653
|
+
end
|
654
|
+
|
615
655
|
|
616
656
|
# ソケットとIDの対応
|
617
657
|
def socket_list_init
|
@@ -633,7 +673,7 @@ EOF
|
|
633
673
|
def dango_server_send_encrypt(str) # 継承用
|
634
674
|
str
|
635
675
|
end
|
636
|
-
def
|
676
|
+
def send_encrypt(str) # フレームワークから呼ばれる部分
|
637
677
|
dango_server_send_encrypt(str)
|
638
678
|
end
|
639
679
|
|
@@ -641,32 +681,38 @@ EOF
|
|
641
681
|
def dango_server_receive_decrypt(str) # 継承用
|
642
682
|
str
|
643
683
|
end
|
644
|
-
def
|
684
|
+
def receive_decrypt(str) # フレームワークから呼ばれる部分
|
645
685
|
dango_server_receive_decrypt(str)
|
646
686
|
end
|
647
687
|
|
648
688
|
# GCスレッドの開始(メモリ使用量統計も含む)
|
649
689
|
def gc_thread_start
|
650
690
|
th = Thread.start do
|
691
|
+
Thread.current[:_name] = "thread_gc"
|
651
692
|
loop do
|
652
693
|
begin
|
653
694
|
sleep @gc_interval_sec
|
654
695
|
|
655
|
-
|
656
|
-
|
696
|
+
logger.debug "mpth:1:GC start mutex start"
|
697
|
+
@mutex_proc_thread.timeout_sync(4, :gc) do
|
698
|
+
logger.debug "mpth:2:GC start #{Time.now_to_s}"
|
657
699
|
gc_start_time = Time.now
|
658
700
|
GC.enable
|
659
701
|
GC.start
|
660
702
|
GC.disable
|
661
703
|
logger.debug "GC end #{Time.now - gc_start_time}sec "
|
662
704
|
end
|
705
|
+
logger.debug "GC start mutex end"
|
663
706
|
|
664
707
|
output_memory_statistics() if @statistics_process_memory # メモリ使用量統計
|
665
708
|
|
709
|
+
rescue DangoFrameworkMutexTimeoutException
|
710
|
+
logger.warn "DangoFrameworkMutexTimeoutException gc_thread_start" +
|
711
|
+
"#{error_message($!, 'u')}"
|
666
712
|
rescue Exception
|
667
713
|
logger.error "Exception gc_thread_start #{error_message($!, 'u')}"
|
668
714
|
end
|
669
|
-
end
|
715
|
+
end # loop end
|
670
716
|
end
|
671
717
|
th.priority = 3
|
672
718
|
end
|
@@ -699,16 +745,16 @@ EOF
|
|
699
745
|
shared[:_heart_beat_time_hash] = {}
|
700
746
|
|
701
747
|
th = Thread.start do
|
702
|
-
|
748
|
+
Thread.current[:_name] = "thread_heart_beat"
|
703
749
|
loop do
|
704
750
|
begin
|
705
751
|
sleep @herat_beat_interval_sec
|
706
752
|
|
707
753
|
next if @gserver.stopped? # gserverが起動していればスキップ
|
708
754
|
|
709
|
-
logger.debug "heart_beat_thread_start "
|
710
|
-
|
711
|
-
|
755
|
+
logger.debug "mpth:1:heart_beat_thread_start "
|
756
|
+
@mutex_proc_thread.timeout_sync(4, :heart_beat_thread) do
|
757
|
+
logger.debug "mpth:2:heart_beat_thread_start "
|
712
758
|
# クライアントから来るハートビートのチェック
|
713
759
|
heart_beat_time_hash = shared[:_heart_beat_time_hash]
|
714
760
|
|
@@ -717,62 +763,53 @@ EOF
|
|
717
763
|
sock = socket_list[sid]
|
718
764
|
|
719
765
|
if ! sock # すでにsocketが無い場合は、スキップ
|
720
|
-
logger.warn "!!!! heart_beat_thread_start:sock is not found. #{sid}:#{sock}"
|
766
|
+
logger.warn "!!!! heart_beat_thread_start:sock is not found. #{sid}:#{sock.object_id}"
|
767
|
+
shared.transaction(:_heart_beat_time_hash) do |hbt_hash|
|
768
|
+
hbt_hash.delete(sid)
|
769
|
+
shared.commit(hbt_hash)
|
770
|
+
end
|
721
771
|
next
|
722
772
|
end
|
723
773
|
|
724
774
|
# クライアントから来たハートビートの時間チェックし、古ければsocketを閉じる
|
725
775
|
if heart_beat_time_hash[sid] &&
|
726
776
|
heart_beat_time_hash[sid] < Time.now - @heart_beat_receive_wait_sec
|
777
|
+
|
727
778
|
logger.warn "!!!! heart_beat_thread_start:heart beat old:#{sid}:" +
|
728
|
-
"#{heart_beat_time_hash[sid]}:#{sock}:#{sock.closed?}"
|
779
|
+
"#{heart_beat_time_hash[sid]}:#{sock.object_id}:#{sock.closed?}"
|
780
|
+
|
781
|
+
shared.transaction(:_heart_beat_time_hash) do |hbt_hash|
|
782
|
+
hbt_hash.delete(sid)
|
783
|
+
shared.commit(hbt_hash)
|
784
|
+
end
|
785
|
+
|
729
786
|
begin
|
730
|
-
@mutex_sock[sock.object_id].
|
787
|
+
@mutex_sock[sock.object_id].timeout_sync(2, "hb_close #{sock.object_id}") do
|
731
788
|
sock.close
|
732
|
-
end
|
789
|
+
end
|
733
790
|
rescue IOError
|
734
|
-
logger.debug "heart_beat_thread_start:maybe already closed. IOError:#{sid}:#{sock}"
|
735
|
-
rescue
|
791
|
+
logger.debug "heart_beat_thread_start:maybe already closed. IOError:#{sid}:#{sock.object_id}"
|
792
|
+
rescue Exception
|
736
793
|
logger.warn "heart_beat_thread_start:failed close socket:#{error_message($!, 'u')}"
|
737
794
|
end
|
738
795
|
next
|
739
796
|
end
|
740
797
|
end # socket_list
|
798
|
+
|
741
799
|
end # @mutex_proc_thread
|
800
|
+
logger.debug "heart_beat_thread_start end"
|
742
801
|
|
743
|
-
|
744
|
-
|
745
|
-
#
|
746
|
-
# if count % 100 == 0
|
747
|
-
# sids = socket_list.all_sid
|
748
|
-
# thr_list = @thr_gr_gserver_serve.list.collect{|th| th.object_id }
|
749
|
-
#
|
750
|
-
# logger.debug "heart_beat_thread_start:sids=#{sids.inspect}"
|
751
|
-
# logger.debug "heart_beat_thread_start:thr_list=#{thr_list.inspect}"
|
752
|
-
# logger.debug "heart_beat_thread_start:sids-thr_list=#{(sids-thr_list).inspect}"
|
753
|
-
# logger.debug "heart_beat_thread_start:thr_list-sids=#{(thr_list-sids).inspect}"
|
754
|
-
# end
|
755
|
-
# end
|
756
|
-
|
802
|
+
rescue DangoFrameworkMutexTimeoutException
|
803
|
+
logger.warn "DangoFrameworkMutexTimeoutException heart_beat_thread_start" +
|
804
|
+
"#{error_message($!, 'u')}"
|
757
805
|
rescue Exception
|
758
806
|
logger.error "Exception heart_beat_thread_start #{error_message($!, 'u')}"
|
759
807
|
end
|
760
|
-
end
|
808
|
+
end # loop end
|
761
809
|
end
|
762
810
|
th.priority = 1
|
763
811
|
end
|
764
812
|
|
765
|
-
# クライアントから来たheart_beatなら
|
766
|
-
def dango_receive__notice_heart_beat(ret_obj)
|
767
|
-
logger.debug "dango_receive__notice_heart_beat:#{session[:sid]}:#{ret_obj['_hb_id']} "
|
768
|
-
|
769
|
-
shared.transaction(:_heart_beat_time_hash) do |heart_beat_time_hash|
|
770
|
-
heart_beat_time_hash[session[:sid]] = Time.now
|
771
|
-
heart_beat_time_hash
|
772
|
-
shared.commit(heart_beat_time_hash)
|
773
|
-
end
|
774
|
-
end
|
775
|
-
|
776
813
|
# サーバーからクライアントへのデータ返信
|
777
814
|
def send_return(send_obj, options = {})
|
778
815
|
logger.info "send_return(#{session[:sid].inspect}) "
|
@@ -805,8 +842,15 @@ EOF
|
|
805
842
|
send_id = notice_name.to_s + Time.now.to_f.to_s + rand().to_s
|
806
843
|
send_obj_dup["_id"] = send_id
|
807
844
|
|
808
|
-
|
809
|
-
|
845
|
+
# queue_send_noticeに排他処理
|
846
|
+
begin
|
847
|
+
@mutex_send_notice.timeout_sync(10, :queue_push) do
|
848
|
+
@queue_send_notice.push([sid, send_obj_dup, encode_type].deep_dup)
|
849
|
+
end
|
850
|
+
rescue DangoFrameworkMutexTimeoutException
|
851
|
+
logger.warn "mutex_send_notice #{error_message($!, 'u')}"
|
852
|
+
rescue Exception
|
853
|
+
logger.error "mutex_send_notice #{error_message($!, 'u')}"
|
810
854
|
end
|
811
855
|
end # end sids.each
|
812
856
|
|
@@ -815,6 +859,7 @@ EOF
|
|
815
859
|
|
816
860
|
# thread for send_notice_queue
|
817
861
|
def thread_send_notice_queue()
|
862
|
+
Thread.current[:_name] = "thread_send_notice_queue"
|
818
863
|
loop do
|
819
864
|
begin
|
820
865
|
before_time = Time.now
|
@@ -824,7 +869,8 @@ EOF
|
|
824
869
|
pop_data = @queue_send_notice.pop
|
825
870
|
send_data_list.push(pop_data) # Queueデータ待ち
|
826
871
|
|
827
|
-
|
872
|
+
# queue_send_noticeに排他処理(sizeとpopの実行の間にpushが起きないように)
|
873
|
+
@mutex_send_notice.timeout_sync(10, :queue_pop) do
|
828
874
|
@queue_send_notice.size.times do
|
829
875
|
# while(! @queue_send_notice.empty?) do # 残りのデータもQueueに入れていく
|
830
876
|
pop_data = @queue_send_notice.pop
|
@@ -848,25 +894,32 @@ EOF
|
|
848
894
|
sock = socket_list[sid]
|
849
895
|
|
850
896
|
if !sock
|
851
|
-
logger.info "thread_send_notice_queue:not found sid=#{sid} sock=#{sock.
|
897
|
+
logger.info "thread_send_notice_queue:not found sid=#{sid} sock=#{sock.object_id}"
|
852
898
|
next
|
853
899
|
end
|
854
900
|
|
855
901
|
if sock.closed?
|
856
|
-
logger.info "thread_send_notice_queue:socket closed. sid=#{sid} sock=#{sock.
|
902
|
+
logger.info "thread_send_notice_queue:socket closed. sid=#{sid} sock=#{sock.object_id}"
|
857
903
|
next
|
858
904
|
end
|
859
905
|
|
860
906
|
begin
|
861
|
-
logger.debug "thread_send_notice_queue:dango_send_data:sid=#{sid} sock=#{sock.
|
907
|
+
logger.debug "thread_send_notice_queue:dango_send_data:sid=#{sid} sock=#{sock.object_id} " +
|
862
908
|
"#{one_send_data_list.collect{|d| d['_notice_name'] + ','}}"
|
863
909
|
|
864
|
-
@mutex_sock[sock.object_id].
|
910
|
+
@mutex_sock[sock.object_id].timeout_sync(2, "send #{sock.object_id}") do
|
865
911
|
dango_send_data(sock, one_send_data_list, :type=>send_data_encode_type_list[sid]) # データ送信
|
866
|
-
end
|
912
|
+
end
|
867
913
|
|
868
914
|
rescue DangoFrameworkConnectionException
|
869
|
-
logger.info "thread_send_notice_queue:failed send. sid=#{sid}
|
915
|
+
logger.info "thread_send_notice_queue:failed send. sid=#{sid} " +
|
916
|
+
"sock=#{sock.object_id} #{$!.class}"
|
917
|
+
rescue DangoFrameworkMutexTimeoutException
|
918
|
+
logger.warn "thread_send_notice_queue:failed send. sid=#{sid} " +
|
919
|
+
"sock=#{sock.object_id} #{$!.class}"
|
920
|
+
rescue Exception
|
921
|
+
logger.error "thread_send_notice_queue:unknown failed. sid=#{sid} " +
|
922
|
+
"sock=#{sock.object_id} #{error_message($!, 'u')}"
|
870
923
|
end
|
871
924
|
end
|
872
925
|
|
@@ -877,10 +930,13 @@ EOF
|
|
877
930
|
|
878
931
|
sleep @send_receive_sleep_interval_sec # スリープ
|
879
932
|
|
933
|
+
rescue DangoFrameworkMutexTimeoutException
|
934
|
+
logger.warn "ERROR:thread_send_notice_queue:DangoFrameworkMutexTimeoutException" +
|
935
|
+
"#{error_message($!, 'u')}"
|
880
936
|
rescue Exception
|
881
|
-
logger.
|
937
|
+
logger.error "ERROR:thread_send_notice_queue:Exception:#{error_message($!, 'u')}"
|
882
938
|
end
|
883
|
-
end
|
939
|
+
end # loop end
|
884
940
|
end
|
885
941
|
|
886
942
|
# 必要に応じて追加するメソッド
|
@@ -903,9 +959,10 @@ EOF
|
|
903
959
|
|
904
960
|
# メインループ用の定義をするためのメソッド
|
905
961
|
def set_loop_setting(options={})
|
906
|
-
logger.debug "loop_setting options:#{options.inspect}"
|
907
962
|
options = options.deep_dup
|
908
963
|
|
964
|
+
shared[:_is_server_sleep] = nil # メンテナンス停止用
|
965
|
+
|
909
966
|
if options["method_name"] # メソッド名が無ければ処理しない
|
910
967
|
method_name = options["method_name"]
|
911
968
|
|
@@ -914,23 +971,36 @@ EOF
|
|
914
971
|
logger.warn "set_loop_setting wait_sec:#{wait_sec.inspect} method_name=#{method_name}"
|
915
972
|
|
916
973
|
th = Thread.new do
|
917
|
-
|
918
|
-
|
974
|
+
logger.debug "set_loop_setting start"
|
975
|
+
count = 0
|
976
|
+
|
977
|
+
loop do
|
978
|
+
begin
|
919
979
|
before_time = Time.now
|
920
|
-
@mutex_proc_thread.synchronize do
|
921
|
-
begin
|
922
|
-
__send__(method_name)
|
923
|
-
rescue Exception
|
924
|
-
logger.error "set_loop_setting error:#{error_message($!, 'u')}"
|
925
|
-
end
|
926
|
-
end
|
927
980
|
|
928
|
-
|
981
|
+
logger.debug "mpth:1:sls start"
|
982
|
+
@mutex_proc_thread.timeout_sync(4, "set_loop_setting_send_#{method_name}") do
|
983
|
+
__send__(method_name)
|
984
|
+
end # mutex_proc_thread
|
985
|
+
logger.debug "mpth:2:sls end"
|
986
|
+
# if count % 1000 == 0
|
929
987
|
|
988
|
+
real_wait_sec = wait_sec - (Time.now - before_time)
|
930
989
|
sleep real_wait_sec if real_wait_sec > 0
|
990
|
+
|
991
|
+
count += 1
|
992
|
+
count = 0 if count >= 10000000
|
993
|
+
|
994
|
+
# メンテナンス機能
|
995
|
+
if shared[:_is_server_sleep]
|
996
|
+
logger.info "set_loop_setting SLEEP !!!"
|
997
|
+
sleep 10000
|
998
|
+
end
|
999
|
+
rescue DangoFrameworkMutexTimeoutException
|
1000
|
+
logger.warn "set_loop_setting error:#{error_message($!, 'u')}"
|
1001
|
+
rescue Exception
|
1002
|
+
logger.error "set_loop_setting error:#{error_message($!, 'u')}"
|
931
1003
|
end
|
932
|
-
rescue Exception
|
933
|
-
logger.error "set_loop_setting error:#{error_message($!, 'u')}"
|
934
1004
|
end
|
935
1005
|
end # th.end
|
936
1006
|
end
|