dango 0.2.3 → 0.2.4
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/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.
|