dango 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +0 -0
- data/README.txt +0 -0
- data/lib/dango/client_framework.rb +0 -0
- data/lib/dango/framework_base.rb +4 -1
- data/lib/dango/monitor/dango_monitor_client.rb +0 -0
- data/lib/dango/monitor/server_monitor_action.rb +0 -0
- data/lib/dango/mutex_socket_list.rb +0 -0
- data/lib/dango/script/dango_server.rb +0 -0
- data/lib/dango/server_framework.rb +58 -223
- data/lib/dango/session_manager.rb +61 -0
- data/lib/dango/shared/memory_store.rb +0 -0
- data/lib/dango/socket_list.rb +0 -0
- data/lib/dango/tasks/dango_rake.rb +0 -0
- data/lib/dango/tester/dango_tester_client.rb +8 -158
- data/lib/dango/version.rb +1 -1
- data/setup.rb +0 -0
- data/test/test_dango.rb +0 -0
- data/test/test_helper.rb +0 -0
- metadata +4 -3
data/LICENSE
CHANGED
File without changes
|
data/README.txt
CHANGED
File without changes
|
File without changes
|
data/lib/dango/framework_base.rb
CHANGED
@@ -225,7 +225,7 @@ module DangoFrameworkModule
|
|
225
225
|
|
226
226
|
# データ送信処理
|
227
227
|
def dango_send_data(sock, send_objs, options = {})
|
228
|
-
# logger.debug "dango_send_data:
|
228
|
+
# logger.debug "dango_send_data:sock=#{sock.inspect} dtype=#{dtype}"
|
229
229
|
|
230
230
|
dtype = options[:type] || DefaultDataType
|
231
231
|
|
@@ -239,6 +239,9 @@ module DangoFrameworkModule
|
|
239
239
|
send_data_orig = Marshal.dump(send_objs)
|
240
240
|
end
|
241
241
|
|
242
|
+
# logger.debug "dango_send_data:#{send_data_orig.inspect}"
|
243
|
+
# logger.debug "dango_send_data:#{dango_send_encrypt(send_data_orig).inspect}"
|
244
|
+
|
242
245
|
send_data = dango_send_encrypt(send_data_orig) + "\n"
|
243
246
|
# send_data = dango_send_encrypt(send_data_orig) + "\r\n"
|
244
247
|
# send_data = dango_send_encrypt(send_data_orig) + "\015\012"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -9,14 +9,16 @@ require 'digest/md5'
|
|
9
9
|
|
10
10
|
require "dango/framework_base"
|
11
11
|
require "dango/socket_list"
|
12
|
+
require "dango/version"
|
12
13
|
require "dango/mutex_socket_list"
|
14
|
+
require "dango/session_manager"
|
13
15
|
require "dango/monitor/server_monitor_action"
|
14
16
|
|
15
17
|
# フレームワーククラス
|
16
18
|
class DangoServerFramework
|
17
19
|
include DangoFrameworkModule
|
18
20
|
|
19
|
-
|
21
|
+
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
|
20
22
|
|
21
23
|
### 以下すべてデフォルト値
|
22
24
|
DefaultNetworkPort = 15000 # デフォルトのポート番号
|
@@ -24,7 +26,7 @@ class DangoServerFramework
|
|
24
26
|
DefaultServerHost = 'localhost' # 接続制限ホスト "0.0.0.0"にすれば全接続オッケイ
|
25
27
|
DefaultMaxConnections = 10 # デフォルトの最大接続人数
|
26
28
|
|
27
|
-
DefaultLogFile = "log/dango_#{
|
29
|
+
DefaultLogFile = "log/dango_#{RAILS_ENV}.log"
|
28
30
|
DefaultLogLevel = Logger::INFO
|
29
31
|
DefaultLogMaxSize = 1048576
|
30
32
|
DefaultLogShiftAge = 99
|
@@ -38,9 +40,11 @@ class DangoServerFramework
|
|
38
40
|
# HeartBeatResponseWaitSec = 10.0 # S=>Cのheart beatの返信待ち秒数
|
39
41
|
HeartBeatReceiveWaitSec = 30.0 # C=>Sのheart beatの受信待ち秒数
|
40
42
|
GCIntervalSec = 5.0 # GCの発生タイミング
|
43
|
+
StatisticsProcessMemoryCount = 100 # GCがこの回数起きた時に統計を取る
|
41
44
|
|
42
45
|
ServerStopWait = 0.2 # サーバー停止時のGServerの確認待ち時間
|
43
46
|
|
47
|
+
|
44
48
|
class DangoGServer < GServer
|
45
49
|
def initialize(parent, *args)
|
46
50
|
@parent = parent
|
@@ -76,6 +80,7 @@ class DangoServerFramework
|
|
76
80
|
logger.info "socket_list.keys:#{socket_list.keys.inspect}"
|
77
81
|
socket_list.keys.each do |sk|
|
78
82
|
logger.debug "sk:#{socket_list[sk].inspect}"
|
83
|
+
next if ! socket_list[sk]
|
79
84
|
socket_list[sk].close if ! socket_list[sk].closed?
|
80
85
|
socket_list[sk]
|
81
86
|
end
|
@@ -158,16 +163,17 @@ class DangoServerFramework
|
|
158
163
|
set_server_variables() # 各種サーバー仕様の変数設定
|
159
164
|
|
160
165
|
logger.warn("===== server initialize =====") # loggerの準備
|
161
|
-
logger.warn("ENV['RAILS_ENV']=#{ENV['RAILS_ENV']}")
|
162
|
-
logger.warn("Process.pid=#{Process.pid}")
|
163
166
|
logger.warn("network_port=#{@network_port}")
|
164
167
|
logger.warn("network_host=#{@network_host}")
|
165
168
|
logger.warn("server_host=#{@server_host}")
|
166
169
|
logger.warn("max_connections=#{@server_max_connections}")
|
170
|
+
logger.warn("RAILS_ENV=#{RAILS_ENV}")
|
171
|
+
logger.warn("Process.pid=#{Process.pid}")
|
172
|
+
logger.warn("Dango Version=#{Dango::VERSION::STRING}")
|
173
|
+
# logger.debug("$LOADED_FEATURES=#{$LOADED_FEATURES.pretty_inspect}")
|
167
174
|
|
168
|
-
|
175
|
+
@session_manager = SessionManager.new # セッション情報の初期化
|
169
176
|
shared_init() # 共有メモリを初期化
|
170
|
-
notice_shared_init() # 通知共有メモリを初期化
|
171
177
|
socket_list_init() # ソケット一覧を初期化
|
172
178
|
mutex_socket_list_init() # ソケット毎用のmutexを初期化
|
173
179
|
@mutex_proc_thread = Mutex.new # スレッドが同時起動しないようにするためのMutex
|
@@ -280,7 +286,7 @@ class DangoServerFramework
|
|
280
286
|
|
281
287
|
# gserverのserveメソッド:スレッド開始処理
|
282
288
|
def thread_main(sock)
|
283
|
-
logger.info "
|
289
|
+
logger.info "thread_main:connect. sock=#{sock} thread.current=#{Thread.current.object_id}"
|
284
290
|
|
285
291
|
@thr_gr_gserver_serve.add(Thread.current) # スレッドグループに登録
|
286
292
|
|
@@ -288,9 +294,11 @@ class DangoServerFramework
|
|
288
294
|
sock.binmode
|
289
295
|
sock.sync = true
|
290
296
|
|
291
|
-
|
292
|
-
|
293
|
-
|
297
|
+
@session_manager.start_session() # sessionの開始処理 sidは自動生成
|
298
|
+
sid = session[:sid]
|
299
|
+
|
300
|
+
logger.debug "thread_main:start_session. sid=#{sid} sock=#{sock} thread.current=#{Thread.current.object_id}"
|
301
|
+
|
294
302
|
socket_list.add(sid, sock)
|
295
303
|
mutex_socket_list.add(sid)
|
296
304
|
|
@@ -357,8 +365,8 @@ EOF
|
|
357
365
|
send_notice("_notice_sid", sid, send_obj)
|
358
366
|
logger.debug "_notice_sid #{sid} "
|
359
367
|
|
360
|
-
session[:connected] = true
|
361
368
|
dango_connect() # 接続時メソッド呼び出し
|
369
|
+
session[:connected] = true
|
362
370
|
end
|
363
371
|
|
364
372
|
ret_objs.each do |ret_obj| # 受信データループ
|
@@ -436,7 +444,9 @@ EOF
|
|
436
444
|
begin
|
437
445
|
if !is_flash_policy_file # Flash Policy Fileなら切断処理不要
|
438
446
|
logger.info "#{sock.inspect} #{sid} is closing"
|
439
|
-
|
447
|
+
if session[:connected] # dango_connect()が実行済みなら
|
448
|
+
dango_close() # 接続解除時に呼び出されるメソッド
|
449
|
+
end
|
440
450
|
end
|
441
451
|
rescue Exception
|
442
452
|
logger.error "#{sock.inspect} #{sid} ERROR\n#{error_message($!, 'u')}"
|
@@ -452,8 +462,9 @@ EOF
|
|
452
462
|
end
|
453
463
|
end
|
454
464
|
|
455
|
-
|
465
|
+
@session_manager.close_session() # sessionの終了処理
|
456
466
|
end
|
467
|
+
|
457
468
|
end
|
458
469
|
|
459
470
|
# action_nameが送信パケットの返事なら
|
@@ -494,6 +505,8 @@ EOF
|
|
494
505
|
@policy_file_allow_domain = @config['server']['policy_file_allow_domain']
|
495
506
|
@policy_file_allow_domain = [@network_host] if @policy_file_allow_domain.class != Array
|
496
507
|
|
508
|
+
@statistics_process_memory = @config['server']['statistics_process_memory'] || false # プロセスのメモリ使用量統計を取る
|
509
|
+
|
497
510
|
# ログレベルの設定
|
498
511
|
log_level_hash = {
|
499
512
|
"FATAL" => Logger::FATAL,
|
@@ -540,118 +553,12 @@ EOF
|
|
540
553
|
end
|
541
554
|
attr_accessor(:shared)
|
542
555
|
|
543
|
-
# 通知共有メモリ
|
544
|
-
def notice_shared_init
|
545
|
-
# @notice_shared = NoticeShared.new(self)
|
546
|
-
@notice_shared = select_shared_database_manager()
|
547
|
-
|
548
|
-
class << @notice_shared ## 各種メソッド追加
|
549
|
-
def initialize2(parent)
|
550
|
-
@parent = parent
|
551
|
-
self[:notice_list] = {}
|
552
|
-
end
|
553
|
-
|
554
|
-
def init_key(key) # そのキーを作成する
|
555
|
-
if self[:notice_list].has_key?(key) || key == :notice_list # キーがすでにあるか予約語なら
|
556
|
-
raise(DangoFrameworkError, "notice_list already has key. key=#{key.inspect}")
|
557
|
-
end
|
558
|
-
|
559
|
-
self.transaction(:notice_list) do |notice_list|
|
560
|
-
notice_list[key] = []
|
561
|
-
notice_list
|
562
|
-
end
|
563
|
-
end
|
564
|
-
|
565
|
-
def add_connectable(key, sid) # 接続許可にする
|
566
|
-
if !self[:notice_list].has_key?(key) # キーがなければ
|
567
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
568
|
-
end
|
569
|
-
|
570
|
-
self.transaction(:notice_list) do |notice_list|
|
571
|
-
notice_list[key] << sid
|
572
|
-
notice_list
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
def remove_connectable(key, sid) # 接続を不許可にする
|
577
|
-
if !self[:notice_list].has_key?(key) # キーがなければ
|
578
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
579
|
-
end
|
580
|
-
|
581
|
-
self.transaction(:notice_list) do |notice_list|
|
582
|
-
notice_list[key].delete(sid)
|
583
|
-
notice_list
|
584
|
-
end
|
585
|
-
end
|
586
|
-
|
587
|
-
def get_connectables(key) # 接続許可一覧を返す
|
588
|
-
if !self[:notice_list].has_key?(key) # キーがなければ
|
589
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
590
|
-
end
|
591
|
-
|
592
|
-
self[:notice_list][key]
|
593
|
-
end
|
594
|
-
|
595
|
-
def notice_change(key, value) # 変更時に通知する変更
|
596
|
-
if !self[:notice_list].has_key?(key) # キーがなければ
|
597
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
598
|
-
end
|
599
|
-
|
600
|
-
self[key] = value
|
601
|
-
|
602
|
-
@parent.logger.debug "self.get_connectables(key):#{self.get_connectables(key).inspect}"
|
603
|
-
|
604
|
-
self.get_connectables(key).each do |sid|
|
605
|
-
@parent.send_notice("notice_shared_#{key}", sid, value)
|
606
|
-
end
|
607
|
-
end
|
608
|
-
|
609
|
-
def not_notice_change(key, value) # 変更時に通知しない変更
|
610
|
-
if !self[:notice_list].has_key?(key) # キーがなければ
|
611
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
612
|
-
end
|
613
|
-
|
614
|
-
self[key] = value
|
615
|
-
end
|
616
|
-
|
617
|
-
def []=(key, value) # データの変更
|
618
|
-
if key != :notice_list && !self[:notice_list].has_key?(key) # キーがなければ
|
619
|
-
raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
|
620
|
-
end
|
621
|
-
|
622
|
-
super(key, value) # データの変更
|
623
|
-
end
|
624
|
-
end
|
625
|
-
end
|
626
|
-
attr_accessor(:notice_shared)
|
627
556
|
|
628
557
|
# セッション
|
629
|
-
def session_init # セッション情報の初期化
|
630
|
-
@session_list = {}
|
631
|
-
# @session_th_list = {}
|
632
|
-
end
|
633
558
|
def session
|
634
|
-
|
635
|
-
Thread.current[:session] = {}
|
636
|
-
@session_list[Thread.current.object_id] = Thread.current[:session]
|
637
|
-
# @session_th_list[Thread.current.object_id] = Thread.current
|
638
|
-
end
|
639
|
-
Thread.current[:session]
|
640
|
-
# sid = Thread.current.object_id
|
641
|
-
# @session[sid] = Session.new if !@session[sid]
|
642
|
-
# @session[sid]
|
643
|
-
end
|
644
|
-
def session_del # セッション情報の初期化
|
645
|
-
begin
|
646
|
-
@session_list.delete(Thread.current.object_id)
|
647
|
-
# @session_th_list.delete(Thread.current)
|
648
|
-
rescue Exception
|
649
|
-
logger.error "ERROR\n#{error_message($!, 'u')}"
|
650
|
-
end
|
559
|
+
@session_manager.session
|
651
560
|
end
|
652
561
|
|
653
|
-
attr_reader(:session_list)
|
654
|
-
# attr_reader(:session_th_list)
|
655
562
|
|
656
563
|
# ソケットとIDの対応
|
657
564
|
def socket_list_init
|
@@ -665,6 +572,7 @@ EOF
|
|
665
572
|
end
|
666
573
|
attr_accessor(:mutex_socket_list)
|
667
574
|
|
575
|
+
|
668
576
|
# 接続時に呼び出されるメソッド
|
669
577
|
def dango_connect
|
670
578
|
end
|
@@ -690,7 +598,7 @@ EOF
|
|
690
598
|
dango_server_receive_decrypt(str)
|
691
599
|
end
|
692
600
|
|
693
|
-
# GCスレッドの開始
|
601
|
+
# GCスレッドの開始(メモリ使用量統計も含む)
|
694
602
|
def gc_thread_start
|
695
603
|
th = Thread.start do
|
696
604
|
loop do
|
@@ -703,9 +611,29 @@ EOF
|
|
703
611
|
GC.enable
|
704
612
|
GC.start
|
705
613
|
GC.disable
|
706
|
-
logger.
|
614
|
+
logger.debug "GC end #{Time.now - gc_start_time}sec "
|
707
615
|
# Thread.critical = false
|
708
616
|
|
617
|
+
# メモリ使用量統計
|
618
|
+
if @statistics_process_memory
|
619
|
+
memory_usage = 0
|
620
|
+
if RUBY_PLATFORM == 'i386-mswin32'
|
621
|
+
require "win32ole"
|
622
|
+
locator = WIN32OLE.new("WbemScripting.SWbemLocator.1") #(A)
|
623
|
+
service = locator.ConnectServer #(B)
|
624
|
+
set = service.ExecQuery("select * from Win32_Process WHERE ProcessId = #{Process.pid}") #(C)
|
625
|
+
set.each do |process|
|
626
|
+
memory_usage = process.PageFileUsage.to_i
|
627
|
+
end
|
628
|
+
else
|
629
|
+
stat = `cat /proc/#{Process.pid}/stat`.split(" ")
|
630
|
+
memory_usage = stat[22].to_i
|
631
|
+
end
|
632
|
+
|
633
|
+
open("log/dango_stat_proc_mem_#{RAILS_ENV}.log", "ab"){|fh| fh.write "#{Time.now_to_s},#{memory_usage},#{@thr_gr_gserver_serve.list.length}\n" }
|
634
|
+
logger.debug "statistics_process_memory file add."
|
635
|
+
end
|
636
|
+
|
709
637
|
rescue Exception
|
710
638
|
logger.error "Exception gc_thread_start #{error_message($!, 'u')}"
|
711
639
|
end
|
@@ -733,6 +661,7 @@ EOF
|
|
733
661
|
# 全員へheart_beatパケットを送信
|
734
662
|
socket_list.keys.each do |sid|
|
735
663
|
sock = socket_list[sid]
|
664
|
+
next if ! sock
|
736
665
|
# logger.debug "heart_beat_thread_start:sid=#{sid} #{sock} #{sock.closed?}"
|
737
666
|
# send_notice("_heart_beat", sid, {}, {:timeout=>@heart_beat_response_wait_sec})
|
738
667
|
|
@@ -811,32 +740,7 @@ EOF
|
|
811
740
|
# send_id = Digest::MD5.hexdigest(sid.to_s + notice_name.to_s + Time.now.to_f.to_s + rand().to_s)
|
812
741
|
send_obj_dup["_id"] = send_id
|
813
742
|
|
814
|
-
|
815
|
-
sock = socket_list[sid]
|
816
|
-
if !sock || sock.closed? # sockがないという事はすでに切断済み
|
817
|
-
logger.info "send_notice:already closed socket. sid=#{sid.inspect} sock=#{sock.inspect} #{sock ? sock.closed? : nil} "
|
818
|
-
return(self)
|
819
|
-
end
|
820
|
-
|
821
|
-
# if !sock
|
822
|
-
# logger.info "send_notice:not found sid=#{sid}"
|
823
|
-
# is_error = true
|
824
|
-
# end
|
825
|
-
|
826
|
-
# if sock.closed?
|
827
|
-
# logger.info "send_notice:socket closed. sid=#{sid}"
|
828
|
-
# is_error = true
|
829
|
-
# end
|
830
|
-
|
831
|
-
# sidの通知の場合はレスポンスを気にしない
|
832
|
-
# if notice_name.to_s == "_notice_sid"
|
833
|
-
dango_send_data(sock, [send_obj_dup], :type=>dtype) # データ送信
|
834
|
-
# else
|
835
|
-
# send_notice_thread(sid, notice_name, send_obj_dup, dtype, timeout, sock) # thread for notice send
|
836
|
-
# end
|
837
|
-
=end
|
838
|
-
|
839
|
-
@queue_send_notice.push([sid, send_obj_dup, dtype])
|
743
|
+
@queue_send_notice.push([sid, send_obj_dup, dtype].deep_dup)
|
840
744
|
end # end sids.each
|
841
745
|
|
842
746
|
# raise(DangoFrameworkConnectionError, "send_notice:error happened.") if is_error
|
@@ -850,7 +754,7 @@ EOF
|
|
850
754
|
begin
|
851
755
|
send_data_list = []
|
852
756
|
send_data_list.push(@queue_send_notice.pop) # Queueデータ待ち
|
853
|
-
logger.debug "thread_send_notice_queue:sending data"
|
757
|
+
# logger.debug "thread_send_notice_queue:sending data"
|
854
758
|
while(! @queue_send_notice.empty?) do # 残りのデータもQueueに入れていく
|
855
759
|
send_data_list.push(@queue_send_notice.pop)
|
856
760
|
end
|
@@ -880,7 +784,12 @@ EOF
|
|
880
784
|
end
|
881
785
|
|
882
786
|
begin
|
787
|
+
logger.debug "thread_send_notice_queue:dango_send_data:sid=#{sid} sock=#{sock.inspect} #{one_send_data_sid.collect{|d| d['notice'] + ','}}"
|
788
|
+
|
789
|
+
# logger.debug one_send_data_sid.pretty_inspect
|
790
|
+
|
883
791
|
dango_send_data(sock, one_send_data_sid, :type=>send_data_dtype_list[sid]) # データ送信
|
792
|
+
|
884
793
|
rescue DangoFrameworkConnectionError
|
885
794
|
logger.info "thread_send_notice_queue:failed send. sid=#{sid} sock=#{sock.inspect} #{$!.class}"
|
886
795
|
end
|
@@ -894,80 +803,6 @@ EOF
|
|
894
803
|
end
|
895
804
|
end
|
896
805
|
|
897
|
-
=begin
|
898
|
-
# thread for notice send
|
899
|
-
def send_notice_thread(sid, notice_name, send_obj_dup, dtype, timeout, sock)
|
900
|
-
Thread.start(sid, notice_name, send_obj_dup, dtype, timeout, sock) do
|
901
|
-
begin
|
902
|
-
@thr_gr_send_notice.add(Thread.current) # send_noticeスレッドグループに登録
|
903
|
-
|
904
|
-
mutex_socket_list.synchronize(sid) do
|
905
|
-
have_came_response = nil
|
906
|
-
|
907
|
-
receive_thread = Thread.start(sock, send_obj_dup, dtype) do
|
908
|
-
begin
|
909
|
-
@thr_gr_send_data.add(Thread.current) # send_dataスレッドグループに登録
|
910
|
-
|
911
|
-
dango_send_data(sock, [send_obj_dup], :type=>dtype) # データ送信
|
912
|
-
rescue DangoFrameworkConnectionError
|
913
|
-
logger.warn "send_notice:DangoFrameworkConnectionError:notice_name=#{notice_name.inspect} #{sid} "
|
914
|
-
rescue DangoFrameworkError
|
915
|
-
logger.warn "ERROR:send_notice:DangoFrameworkError:notice_name=#{notice_name.inspect} #{sid} \n #{error_message($!, 'u')}"
|
916
|
-
rescue Exception
|
917
|
-
logger.warn "ERROR:send_notice:Exception:notice_name=#{notice_name.inspect} #{sid} \n #{error_message($!, 'u')}"
|
918
|
-
end
|
919
|
-
end
|
920
|
-
|
921
|
-
# データ送信スレッドの終了待ち
|
922
|
-
if !receive_thread.join(@send_timeout_sec)
|
923
|
-
# タイムアウトの場合は
|
924
|
-
logger.warn "send_notice:send timeout:#{notice_name} #{sid} "
|
925
|
-
else
|
926
|
-
end_reserved_time = Time.now + timeout
|
927
|
-
|
928
|
-
# タイムアウトチェック
|
929
|
-
catch(:send_timeout) do
|
930
|
-
(timeout.to_f / @send_receive_sleep_interval_sec).to_i.times do
|
931
|
-
sleep @send_receive_sleep_interval_sec # スリープ
|
932
|
-
|
933
|
-
@mutex_send_response.synchronize do # データ送信の返信が来たかどうかの確認
|
934
|
-
find_res = @arr_send_response.find{|r| r[:_id] == send_obj_dup["_id"] && r[:_sid] == sid }
|
935
|
-
|
936
|
-
if find_res
|
937
|
-
logger.debug "send_notice:find_res _heart_beat #{sid}" if notice_name.to_s == "_heart_beat"
|
938
|
-
|
939
|
-
@arr_send_response.delete(find_res)
|
940
|
-
have_came_response = true
|
941
|
-
throw(:send_timeout)
|
942
|
-
end
|
943
|
-
end
|
944
|
-
|
945
|
-
if Time.now > end_reserved_time
|
946
|
-
logger.debug "send_notice:receive timeout:#{notice_name} #{sid} #{end_reserved_time}"
|
947
|
-
|
948
|
-
# このコードは不要なはずだが念の為取っておいてある、安定したことが確認できたら削除する
|
949
|
-
if notice_name.to_s == "_heart_beat" # heart beatだったらsockを止める
|
950
|
-
logger.info "!!!! send_notice:heart_beat timeout"
|
951
|
-
sock.close if !sock.closed?
|
952
|
-
end
|
953
|
-
break
|
954
|
-
end
|
955
|
-
|
956
|
-
end # タイムアウト処理終わり
|
957
|
-
end # catch 終わり
|
958
|
-
|
959
|
-
if !have_came_response # 戻ってきたデータがあるかどうかチェック
|
960
|
-
logger.warn "!!! received data is none:#{notice_name} #{sid} #{send_obj_dup['_id']} "
|
961
|
-
end
|
962
|
-
end
|
963
|
-
end # mutex
|
964
|
-
rescue Exception
|
965
|
-
logger.error "send_response_thread error:#{error_message($!, 'u')}"
|
966
|
-
end
|
967
|
-
end # Thread:end
|
968
|
-
end
|
969
|
-
=end
|
970
|
-
|
971
806
|
# 必要に応じて追加するメソッド
|
972
807
|
def method_missing(name, *args)
|
973
808
|
if name.to_s =~ /^dango_receive_action_notice_shared_(.+)/ # 共有メモリ変更通知なら
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
# sessionとsidの管理(1セッションごとにインスタンス化される)
|
4
|
+
class SessionManager
|
5
|
+
MaxSidCounter = 999999
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@session_list = {}
|
9
|
+
@session_mutex = Mutex.new
|
10
|
+
|
11
|
+
@sid_counter = 0
|
12
|
+
@sid_list = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# session開始
|
17
|
+
def start_session()
|
18
|
+
@session_mutex.synchronize do
|
19
|
+
sid = generate_sid()
|
20
|
+
@session_list[Thread.current.object_id] = {:sid => sid}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# session終了
|
25
|
+
def close_session()
|
26
|
+
@session_mutex.synchronize do
|
27
|
+
drop_sid()
|
28
|
+
@session_list[Thread.current.object_id] = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# sessionへのアクセス
|
33
|
+
def session
|
34
|
+
@session_mutex.synchronize do
|
35
|
+
@session_list[Thread.current.object_id]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# sid情報作成
|
43
|
+
def generate_sid()
|
44
|
+
sid = nil
|
45
|
+
while(sid == nil) do
|
46
|
+
@sid_counter += 1
|
47
|
+
@sid_counter = 1 if @sid_counter > MaxSidCounter
|
48
|
+
sid = @sid_counter if ! @sid_list.has_key?(@sid_counter)
|
49
|
+
end
|
50
|
+
|
51
|
+
@sid_list[sid] = Thread.current.object_id
|
52
|
+
sid
|
53
|
+
end
|
54
|
+
|
55
|
+
# sid削除
|
56
|
+
def drop_sid()
|
57
|
+
@sid_list.delete_if{|sid, oid| oid == Thread.current.object_id }
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
File without changes
|
data/lib/dango/socket_list.rb
CHANGED
File without changes
|
File without changes
|
@@ -142,7 +142,7 @@ class TestClient < DangoClientFramework
|
|
142
142
|
@connection_client_port = @config["network"]["port"] # 自動でこのポートでサーバー開始
|
143
143
|
|
144
144
|
# ログ出力情報
|
145
|
-
@connection_client_log_file = "log/tester_#{@client_name}.log" # 自動でこのログファイル名を使う
|
145
|
+
@connection_client_log_file = "log/tester_#{Process.pid}_#{@client_name}.log" # 自動でこのログファイル名を使う
|
146
146
|
@connection_client_log_level = Logger::DEBUG # 自動でこのログレベルになる
|
147
147
|
end
|
148
148
|
|
@@ -174,124 +174,6 @@ class TestClient < DangoClientFramework
|
|
174
174
|
end
|
175
175
|
|
176
176
|
|
177
|
-
=begin
|
178
|
-
# trap_receive
|
179
|
-
def trap_receive(notice_name, options = {})
|
180
|
-
logger.debug "trap_receive_data:#{notice_name}:"
|
181
|
-
timeout = options[:timeout] || ReceiveTrapTimeoutSec
|
182
|
-
trap_proc = options[:proc] || nil
|
183
|
-
trap_loop = options[:loop] || nil # procがある場合のみ有効なフラグ
|
184
|
-
raise(ArgumentError, ":proc is not Proc class.") if trap_proc && ! trap_proc.is_a?(Proc)
|
185
|
-
|
186
|
-
# 戻ってきたデータのチェックメソッド
|
187
|
-
|
188
|
-
# if ! @receive_methods.include?(notice_name_sym)
|
189
|
-
notice_name_sym = (notice_name.class == Symbol) ? (":"+notice_name.to_s) : ('"'+notice_name+'"')
|
190
|
-
instance_method_name = "dango_receive_#{notice_name}"
|
191
|
-
expr = <<-EOF
|
192
|
-
def self.#{instance_method_name}(ret_obj)
|
193
|
-
logger.debug "ret_obj:#{notice_name_sym}:" + ret_obj.inspect + " " + Time.now_to_s
|
194
|
-
send_receive_shared[#{notice_name_sym}] = ret_obj
|
195
|
-
end
|
196
|
-
EOF
|
197
|
-
instance_eval expr
|
198
|
-
# @receive_methods.push(notice_name_sym)
|
199
|
-
# end
|
200
|
-
|
201
|
-
# @trap_thread_hashにスレッド登録
|
202
|
-
if ! @trap_thread_hash.has_key?(notice_name)
|
203
|
-
|
204
|
-
# スレッド開始
|
205
|
-
th = Thread.start(notice_name, timeout, trap_proc, trap_loop) do
|
206
|
-
loop do
|
207
|
-
send_receive_shared[notice_name] = nil
|
208
|
-
if timeout == 0
|
209
|
-
end_reserved_time = Time.at(0) # 0ならepochを入れる
|
210
|
-
else
|
211
|
-
end_reserved_time = Time.now + timeout # 0以上ならタイムアウト時間決定
|
212
|
-
end
|
213
|
-
|
214
|
-
# タイムアウトチェック
|
215
|
-
loop do
|
216
|
-
if end_reserved_time != Time.at(0) && end_reserved_time < Time.now
|
217
|
-
raise(DangoFrameworkTimeoutError, "timeout:timeout_sec=#{timeout}: \n client_name=#{@client_name}(#{self.sid}): \n notice_name=#{notice_name}")
|
218
|
-
end
|
219
|
-
|
220
|
-
# 戻ってきたデータがあれば
|
221
|
-
if send_receive_shared[notice_name]
|
222
|
-
logger.debug "notice_name:#{notice_name}:#{send_receive_shared[notice_name].inspect} "
|
223
|
-
break
|
224
|
-
end
|
225
|
-
|
226
|
-
sleep SendReceiveSleepIntervalSec # スリープ
|
227
|
-
end
|
228
|
-
|
229
|
-
# 戻ってきたデータがあるかどうかチェック
|
230
|
-
if !send_receive_shared[notice_name]
|
231
|
-
raise(DangoFrameworkError, "received data is none. sid=#{self.sid} notice_name=#{notice_name}")
|
232
|
-
end
|
233
|
-
|
234
|
-
# :procが設定されている場合は、それを呼び出す
|
235
|
-
if trap_proc
|
236
|
-
logger.debug "trap_receive_data:trap_proc:#{trap_proc.inspect} "
|
237
|
-
trap_proc.call(send_receive_shared[notice_name])
|
238
|
-
send_receive_shared[notice_name] = nil
|
239
|
-
break if ! trap_loop # loopする必要がなければスレッド終了
|
240
|
-
|
241
|
-
# :procが設定されていなければ、wait用に@receive_arrに入れておく
|
242
|
-
else
|
243
|
-
@receive_mutex.synchronize do
|
244
|
-
logger.debug "notice_name:#{notice_name}:#{send_receive_shared[notice_name].inspect} "
|
245
|
-
@receive_arr.push([notice_name.deep_dup, send_receive_shared[notice_name].deep_dup])
|
246
|
-
send_receive_shared[notice_name] = nil
|
247
|
-
end
|
248
|
-
break # スレッド終了
|
249
|
-
|
250
|
-
end
|
251
|
-
end # loop
|
252
|
-
|
253
|
-
# メソッドの削除
|
254
|
-
instance_method_name = "dango_receive_#{notice_name}"
|
255
|
-
expr = <<-EOF
|
256
|
-
def self.#{instance_method_name}(ret_obj); end
|
257
|
-
EOF
|
258
|
-
instance_eval expr
|
259
|
-
|
260
|
-
end # Thread
|
261
|
-
|
262
|
-
@trap_thread_hash[notice_name] = th
|
263
|
-
else
|
264
|
-
|
265
|
-
logger.debug "trap_receive_data:already register trap:notice_name:#{notice_name} "
|
266
|
-
end
|
267
|
-
|
268
|
-
logger.debug "trap_receive_data:registered:#{notice_name}:"
|
269
|
-
end
|
270
|
-
|
271
|
-
# cancel trap_receive
|
272
|
-
def cancel_trap_receive(notice_name, options = {})
|
273
|
-
logger.debug "cancel_trap_receive:#{notice_name}:"
|
274
|
-
|
275
|
-
# trapスレッドの削除
|
276
|
-
if @trap_thread_hash[notice_name]
|
277
|
-
logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
|
278
|
-
@trap_thread_hash[notice_name].kill
|
279
|
-
logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
|
280
|
-
@trap_thread_hash[notice_name].join
|
281
|
-
logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
|
282
|
-
|
283
|
-
@trap_thread_hash.delete(notice_name)
|
284
|
-
end
|
285
|
-
|
286
|
-
# 受信データのごみを削除
|
287
|
-
send_receive_shared[notice_name] = nil
|
288
|
-
|
289
|
-
@receive_mutex.synchronize do
|
290
|
-
@receive_arr.delete_if{|r| r[0] == notice_name}
|
291
|
-
end
|
292
|
-
end
|
293
|
-
=end
|
294
|
-
|
295
177
|
# wait_receive
|
296
178
|
def wait_receive(notice_name, options = {})
|
297
179
|
logger.debug "wait_receive_data:#{notice_name}:"
|
@@ -334,51 +216,19 @@ class TestClient < DangoClientFramework
|
|
334
216
|
receive_data[1]
|
335
217
|
end
|
336
218
|
|
337
|
-
|
338
|
-
def
|
219
|
+
# clear_receive notice_nameを省略するとchacheにあるものすべて削除
|
220
|
+
def clear_receive(notice_name = nil, options = {})
|
339
221
|
logger.debug "wait_receive_data:#{notice_name}:"
|
340
|
-
timeout = options[:timeout] || ReceiveWaitTimeoutSec
|
341
|
-
|
342
|
-
# データ受信待ち
|
343
|
-
receive_data = nil
|
344
|
-
|
345
|
-
end_reserved_time = Time.now + timeout # 0以上ならタイムアウト時間決定
|
346
|
-
|
347
|
-
loop do
|
348
|
-
@receive_mutex.synchronize do
|
349
|
-
receive_data = @receive_arr.find{|r| r[0] == notice_name}.deep_dup
|
350
|
-
end
|
351
|
-
|
352
|
-
break if receive_data != nil
|
353
|
-
break if end_reserved_time < Time.now
|
354
|
-
|
355
|
-
sleep SendReceiveSleepIntervalSec # スリープ
|
356
|
-
end
|
357
|
-
|
358
|
-
# タイムアウトなら
|
359
|
-
if receive_data == nil
|
360
|
-
raise(DangoFrameworkTimeoutError, "timeout:timeout_sec=#{timeout}: \n client_name=#{@client_name}(#{self.sid}) \n :notice_name=#{notice_name} \n")
|
361
|
-
end
|
362
222
|
|
363
223
|
# 結果を削除しておく
|
364
|
-
|
365
|
-
|
224
|
+
send_receive_shared.transaction(:receive_cache) do |receive_cache|
|
225
|
+
receive_cache.delete_if do |one_rec_data|
|
226
|
+
true if (! notice_name) || (notice_name && one_rec_data[0] == notice_name)
|
227
|
+
end
|
228
|
+
receive_cache
|
366
229
|
end
|
367
|
-
|
368
|
-
@trap_thread_hash.delete(notice_name)
|
369
|
-
|
370
|
-
receive_data[1]
|
371
230
|
end
|
372
231
|
|
373
|
-
# receive_arrの状態確認
|
374
|
-
def receive_arr
|
375
|
-
receive_arr = nil
|
376
|
-
@receive_mutex.synchronize do
|
377
|
-
receive_arr = @receive_arr.deep_dup
|
378
|
-
end
|
379
|
-
receive_arr
|
380
|
-
end
|
381
|
-
=end
|
382
232
|
|
383
233
|
end
|
384
234
|
|
data/lib/dango/version.rb
CHANGED
data/setup.rb
CHANGED
File without changes
|
data/test/test_dango.rb
CHANGED
File without changes
|
data/test/test_helper.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dango
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke Minami
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05-
|
12
|
+
date: 2008-05-19 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- lib/dango/server_framework.rb
|
47
47
|
- lib/dango/mutex_socket_list.rb
|
48
48
|
- lib/dango/socket_list.rb
|
49
|
+
- lib/dango/session_manager.rb
|
49
50
|
- lib/dango/monitor/dango_monitor_client.rb
|
50
51
|
- lib/dango/monitor/server_monitor_action.rb
|
51
52
|
- lib/dango/script/dango_server.rb
|
@@ -86,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
87
|
requirements: []
|
87
88
|
|
88
89
|
rubyforge_project: dango
|
89
|
-
rubygems_version: 1.
|
90
|
+
rubygems_version: 1.1.1
|
90
91
|
signing_key:
|
91
92
|
specification_version: 2
|
92
93
|
summary: Realtime communications network framework for Ruby and Flash on Rails.
|