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 CHANGED
File without changes
data/README.txt CHANGED
File without changes
File without changes
@@ -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:send_objs=#{send_objs.inspect}"
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
- env = ENV['RAILS_ENV'] || 'development'
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_#{env}.log"
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
- session_init() # セッション情報の初期化
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 "#{sock} is accepted. thread.current=#{Thread.current.object_id} "
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
- sid = Thread.current.object_id.deep_dup
292
- # sid = sock.object_id
293
- session[:sid] = sid
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
- dango_close() # 接続解除時に呼び出されるメソッド
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
- session_del() # @mutex_proc_thread.synchronizeの中だとうまくいかない
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
- if !Thread.current[:session]
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.info "GC end #{Time.now - gc_start_time}sec "
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
- =begin
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
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
- =begin
338
- def wait_receive(notice_name, options = {})
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
- @receive_mutex.synchronize do
365
- @receive_arr.delete_if{|r| r[0] == notice_name}
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
@@ -2,7 +2,7 @@ module Dango #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 3
5
+ TINY = 4
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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.3
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-01 00:00:00 +09:00
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.0.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.