dango 0.4.3 → 0.4.5

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.
@@ -19,8 +19,12 @@ module DangoControllerPlugin
19
19
  config = dango_server_config(options)
20
20
  raise("backdoor_run_drb_server is false.") if !config['server']['backdoor_run_drb_server']
21
21
  drb_uri = "druby://#{config['network']['host']}:#{config['server']['backdoor_run_drb_port']}"
22
- drb_obj = DRbObject.new_with_uri(drb_uri)
23
- drb_obj.__send__(method_name.to_s, arg)
22
+ begin
23
+ drb_obj = DRbObject.new_with_uri(drb_uri)
24
+ drb_obj.__send__(method_name.to_s, arg)
25
+ rescue Exception
26
+ raise("DRbError:#{$!.class} #{$!.message} #{$!.backtrace.inspect}")
27
+ end
24
28
  end
25
29
  end
26
30
 
@@ -68,7 +68,8 @@ module ErrorMessage
68
68
  "#{exception_class.class} is not Exception class"
69
69
  end
70
70
 
71
- str = "#{exception_class.class}:#{exception_class.message}\n#{exception_class.backtrace.pretty_inspect}"
71
+ str = "#{exception_class.class}:#{exception_class.message}\n" +
72
+ "#{exception_class.backtrace.pretty_inspect}"
72
73
  if code.to_s.downcase == "u" || code.to_s.downcase == "utf8"
73
74
  str = str.toutf8
74
75
  elsif code.to_s.downcase == "s" || code.to_s.downcase == "sjis"
@@ -103,6 +104,9 @@ module DangoFrameworkModule
103
104
  CommMaxDigit = 5 # 通信の最大桁数
104
105
  MaxLenRecv = 1024 # 通信の一度の送信バイト数
105
106
  MaxLenSend = 1024 * 1024 # 通信の一度の送信バイト数
107
+ # 4294967296 # 本当はuint最大値なんだけれど、policyファイルの都合で変えてある
108
+ # 1886350440
109
+ # 1886350441
106
110
 
107
111
  EncodeTypeJSON = 0 # エンコードのタイプのJSON
108
112
  EncodeTypeYAML = 1 # エンコードのタイプのYAML
@@ -142,14 +146,14 @@ module DangoFrameworkModule
142
146
  @dango_logger = Logger.new(@log_file, @log_shift_age, @log_max_size)
143
147
  @dango_logger.level = @log_level
144
148
  def @dango_logger.format_message(severity, timestamp, msg, progname)
145
- # "#{Time.now_to_s}:#{sprintf('%1.1s', severity)}:#{progname}:#{msg}\n"
146
- # "%s, [%s#%d] %5s -- %s: %s\n" % [severity[0..0], format_datetime(time), $$, severity, progname,msg2str(msg)]
147
149
  now = Time.now
148
150
  now_str = now.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % now.usec
149
151
  "%1.1s, [%s] %d:%s %s\n" % [severity, now_str, Thread.current.object_id, progname, msg]
150
152
  end
151
153
  end
154
+
152
155
  end
156
+
153
157
  @dango_logger
154
158
  end
155
159
 
@@ -159,17 +163,15 @@ module DangoFrameworkModule
159
163
  def dango_receive_data(sock)
160
164
  ret_data = ""
161
165
 
162
- # logger.debug "dango_receive_data(#{sock})"
163
-
164
166
  begin
165
- # size_str = sock.readpartial(CommMaxDigit + 1)
166
- # size_str = sock.sysread(CommMaxDigit + 1)
167
167
  size_str = sock.recv(CommMaxDigit + 1)
168
168
  rescue EOFError, IOError, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNABORTED
169
169
  # 接続終了時の切断と思われるものはDangoFrameworkConnectionExceptionにしない
170
- raise(DangoFrameworkDisconnectException, "failed to read sock for EOF reached (and so on). sock=#{sock.inspect} #{$!.class} toid=#{Thread.current.object_id}")
170
+ raise(DangoFrameworkDisconnectException, "failed to read sock for EOF reached (and so on). " +
171
+ "sock=#{sock.inspect} #{$!.class} toid=#{Thread.current.object_id}")
171
172
  rescue
172
- raise(DangoFrameworkConnectionException, "failed to read sock. sock=#{sock.inspect} toid=#{Thread.current.object_id}\n#{error_message($!, 'u')}")
173
+ raise(DangoFrameworkConnectionException, "failed to read sock. sock=#{sock.inspect} " +
174
+ "toid=#{Thread.current.object_id}\n#{error_message($!, 'u')}")
173
175
  end
174
176
 
175
177
  if size_str == ""
@@ -189,39 +191,31 @@ module DangoFrameworkModule
189
191
 
190
192
  ## データがない場合
191
193
  if size == nil || size == 0
192
- raise(DangoFrameworkConnectionException, "toid=#{Thread.current.object_id}:size=#{size}:size_str=#{size_str.inspect}")
194
+ raise(DangoFrameworkConnectionException, "toid=#{Thread.current.object_id}" +
195
+ ":size=#{size}:size_str=#{size_str.inspect}")
193
196
  end
194
197
 
195
198
  ## データが大きすぎる場合
196
- if size >= 1886350441
199
+ if size >= MaxLenSend
197
200
  raise(DangoFrameworkConnectionException, "too big... size=#{size}:size_str=#{size_str.inspect}")
198
201
  end
199
202
 
200
- # logger.debug "size=#{size}:size_str=#{size_str.inspect}"
201
-
202
203
  ret_data_orig = ""
203
204
 
204
205
  while size > 0
205
206
  read_len = MaxLenRecv > size ? size : MaxLenRecv
206
207
  begin
207
- # this_ret_data_orig = sock.readpartial(read_len)
208
- # this_ret_data_orig = sock.sysread(read_len)
209
208
  this_ret_data_orig = sock.recv(read_len)
210
209
  rescue
211
210
  raise(DangoFrameworkConnectionException, "failed to read sock(data).\n#{error_message($!, 'u')}")
212
211
  end
213
212
 
214
213
  ret_data_orig += this_ret_data_orig
215
- # logger.debug "size:#{size.inspect}:this_ret_data_orig:#{this_ret_data_orig.inspect}"
216
214
 
217
215
  size -= this_ret_data_orig.size
218
- # logger.debug "size:#{size.inspect}"
219
216
  end
220
217
 
221
- # logger.debug "ret_data_orig:#{ret_data_orig.inspect}"
222
-
223
218
  ret_data = dango_receive_decrypt(ret_data_orig[0..-2])
224
- # logger.debug "ret_data:#{ret_data.inspect}"
225
219
 
226
220
  @recv_count += 1 if @recv_count # 受信回数カウント
227
221
 
@@ -243,8 +237,6 @@ module DangoFrameworkModule
243
237
  # データ送信処理
244
238
  def dango_send_data(sock, send_objs, options = {})
245
239
  encode_type = options[:encode_type] || DefaultEncodeType
246
- # logger.debug "dango_send_data:sock=#{sock.inspect} encode_type=#{encode_type}"
247
- # logger.debug "dango_send_data:send_objs=#{send_objs.inspect}"
248
240
 
249
241
  if send_objs == []
250
242
  send_data_orig = ""
@@ -258,46 +250,25 @@ module DangoFrameworkModule
258
250
  send_data_orig = JSON.generate(send_objs)
259
251
  end
260
252
 
261
- # logger.debug "dango_send_data:#{send_data_orig.inspect}"
262
- # logger.debug "dango_send_data:#{dango_send_encrypt(send_data_orig).inspect}"
263
-
264
253
  send_data = dango_send_encrypt(send_data_orig) + "\n"
265
- # send_data = dango_send_encrypt(send_data_orig) + "\r\n"
266
- # send_data = dango_send_encrypt(send_data_orig) + "\015\012"
267
-
268
- # logger.debug "start dango_send_data:#{send_data.inspect}"
269
254
 
270
255
  size = send_data.size
271
256
 
272
- # if size >= 4294967296 # 本当はuint最大値なんだけれど、policyファイルの都合で変えてある
273
- # if size >= 1886350440
274
257
  if size >= MaxLenSend
275
258
  raise(DangoFrameworkException, "max size over. size:#{size} >= #{MaxLenSend}")
276
259
  end
277
260
 
278
- # size_str = sprintf("%0#{CommMaxDigit}d", size)
279
-
280
261
  size_str = [encode_type, size].pack("cN")
281
- # logger.debug "size=#{size}:size_str=#{size_str.inspect}"
282
-
283
262
  send_buf = size_str + "\n" + send_data
284
- # logger.debug "send_buf:#{send_buf.inspect}"
285
-
286
263
  begin
287
264
  sock.write send_buf
288
265
  sock.flush
289
-
290
- # sock.send(send_buf, 0)
291
- # sock.flush
292
-
293
266
  rescue
294
267
  raise(DangoFrameworkConnectionException, "sock write failed.\n#{error_message($!, 'u')}")
295
268
  end
296
269
 
297
270
  @send_count += 1 if @send_count # 受信回数カウント
298
- # logger.debug "finish dango_send_data:#{send_data.inspect}"
299
- # logger.debug "finish dango_send_data:toid=#{Thread.current.object_id} #{sock} #{sock.closed?}"
300
-
271
+
301
272
  sock
302
273
  end
303
274
  end
@@ -8,11 +8,11 @@ require 'ipaddr'
8
8
 
9
9
  # メインクラス
10
10
  class ServerMonitorAction
11
- def initialize(parent, config, sock, ret_obj)
11
+ def initialize(parent, config, peerhost, peeraddr, ret_obj)
12
12
  @parent = parent
13
13
  @config = config
14
14
 
15
- @logger = @parent.logger
15
+ @logger = @parent.logger
16
16
  @shared = @parent.shared
17
17
  @session = @parent.session
18
18
  @socket_list = @parent.socket_list
@@ -21,7 +21,7 @@ class ServerMonitorAction
21
21
  # アクション名
22
22
  action_name = ret_obj["action"].to_s
23
23
 
24
- dango_check_monitor_error(sock, action_name)
24
+ dango_check_monitor_error(peerhost, peeraddr, action_name)
25
25
 
26
26
  if action_name == '_monitor_all_info' # メンテナンスアクション名なら
27
27
  dango_server_monitor_all_info(ret_obj)
@@ -50,8 +50,7 @@ class ServerMonitorAction
50
50
  private
51
51
 
52
52
  # メンテナンスコマンド:エラーの場合
53
- def dango_check_monitor_error(sock, action_name)
54
- peerhost, peeraddr = sock.peeraddr[2, 2]
53
+ def dango_check_monitor_error(peerhost, peeraddr, action_name)
55
54
  backdoor_host = @backdoor_host
56
55
  logger.debug "dango_check_monitor_error:peerhost=#{peerhost.inspect} peeraddr=#{peeraddr.inspect} backdoor_host=#{backdoor_host.inspect}"
57
56
 
@@ -73,7 +73,7 @@ class DangoServerFramework
73
73
  def exit_process() # プロセス終了処理
74
74
  debug_print("shutdown")
75
75
  begin
76
- File.delete(@pid_file)
76
+ # File.delete(@pid_file)
77
77
  rescue
78
78
  # puts "failed delete file. #{@pid_file}:#{$!.class}:#{$!.message}"
79
79
  end
@@ -145,17 +145,19 @@ class DangoServerFramework
145
145
  logger.warn("Dango Version=#{Dango::VERSION::STRING}")
146
146
  # logger.debug("$LOADED_FEATURES=#{$LOADED_FEATURES.pretty_inspect}")
147
147
 
148
- shared_init() # 共有メモリを初期化
149
- socket_list_init() # ソケット一覧を初期化
150
- @session_manager = SessionManager.new(shared) # セッション情報の初期化
151
- @mutex_proc_thread = Mutex.new # スレッドが同時起動しないようにするためのMutex
152
- heart_beat_thread_start() # ハートビートスレッドの開始
153
- gc_thread_start() # GCスレッドの開始
148
+ shared_init() # 共有メモリを初期化
149
+ socket_list_init() # ソケット一覧を初期化
150
+ @mutex_sock = {} # ソケットの排他処理ハッシュ
151
+ @session_manager = SessionManager.new(shared, RAILS_ENV) # セッション情報の初期化
154
152
 
155
- dango_server_init() # 初期設定読み込み
153
+ @mutex_proc_thread = Mutex.new # スレッドが同時起動しないようにするためのMutex
154
+ heart_beat_thread_start() # ハートビートスレッドの開始
155
+ gc_thread_start() # GCスレッドの開始
156
156
 
157
- @mutex_send_response = Mutex.new # 送信レスポンス用のMutex
158
- @arr_send_response = [] # 送信レスポンス用のキャッシュ
157
+ dango_server_init() # 初期設定読み込み
158
+
159
+ @mutex_send_response = Mutex.new # 送信レスポンス用のMutex
160
+ @arr_send_response = [] # 送信レスポンス用のキャッシュ
159
161
 
160
162
 
161
163
  TCPSocket.do_not_reverse_lookup = true # 逆引きを行わない
@@ -274,15 +276,20 @@ class DangoServerFramework
274
276
  @thr_gr_gserver_serve.add(Thread.current) # スレッドグループに登録
275
277
 
276
278
  begin
277
- sock.binmode
278
- sock.sync = true
279
-
280
279
  @session_manager.start_session() # sessionの開始処理 sidは自動生成
281
280
  sid = session[:sid]
282
281
 
283
- session[:peer_addr] = sock.peeraddr
284
- session[:peer_ip_address] = sock.peeraddr[3]
285
- session[:peer_host] = sock.peeraddr[2]
282
+ # sockに対しての=nil write close などの書き換えに対する排他処理
283
+ @mutex_sock[sock.object_id] = Mutex.new
284
+
285
+ @mutex_sock[sock.object_id].synchronize do
286
+ sock.binmode
287
+ sock.sync = true
288
+
289
+ session[:peer_addr] = sock.peeraddr
290
+ session[:peer_ip_address] = sock.peeraddr[3]
291
+ session[:peer_host] = sock.peeraddr[2]
292
+ end
286
293
 
287
294
  session[:encode_type] = DefaultEncodeType
288
295
 
@@ -315,29 +322,8 @@ class DangoServerFramework
315
322
  end
316
323
 
317
324
  if is_flash_policy_file # Flashのポリシーファイルが来たら
318
- logger.debug "is_flash_policy_file"
319
-
320
- if @policy_file_request # ポリシーファイルを返す設定なら
321
- logger.info "is_flash_policy_file #{sid} #{@policy_file_request}"
322
-
323
- allow_str = ""
324
-
325
- @policy_file_allow_domain.each do |one_host|
326
- allow_str += %Q|<allow-access-from domain="#{one_host}" to-ports="#{@policy_file_allow_port.join(',')}" />|
327
- allow_str += "\n"
328
- end
329
-
330
- policy_data = <<EOF
331
- <?xml version="1.0"?>
332
- <cross-domain-policy>
333
- #{allow_str}
334
- </cross-domain-policy>
335
- EOF
336
-
337
- logger.debug policy_data
338
- sock.write policy_data
339
- sock.flush
340
- logger.info "policy file sent."
325
+ @mutex_sock[sock.object_id].synchronize do
326
+ do_flash_policy_file(sid, sock)
341
327
  end
342
328
 
343
329
  # この部分はポリシーファイルを返す設定に関係なく実行する部分
@@ -369,7 +355,9 @@ EOF
369
355
  @mutex_proc_thread.synchronize do
370
356
 
371
357
  if action_name[0, 9] == '_monitor_' # メンテナンスアクション名なら
372
- ServerMonitorAction.new(self, @config, sock, ret_obj)
358
+ peerhost = session[:peer_host]
359
+ peeraddr = session[:peer_ip_address]
360
+ ServerMonitorAction.new(self, @config, peerhost, peeraddr, ret_obj)
373
361
 
374
362
  elsif action_name == '_response' # 送信パケットの返事なら
375
363
  action_name_is_response(ret_obj)
@@ -447,8 +435,9 @@ EOF
447
435
  ensure
448
436
  socket_list.delete(sid) # ソケットリストから削除
449
437
  begin
450
- # sock.close if !sock.closed? # ソケットを閉じる
451
- sock.close # ソケットを閉じる
438
+ @mutex_sock[sock.object_id].synchronize do
439
+ sock.close # ソケットを閉じる
440
+ end
452
441
  rescue IOError
453
442
  logger.info "IOError #{sock.inspect} #{sid}"
454
443
  rescue Exception
@@ -456,7 +445,10 @@ EOF
456
445
  end
457
446
 
458
447
  logger.info "#{sock.inspect} #{sid} is closed"
459
- sock = nil
448
+ @mutex_sock[sock.object_id].synchronize do
449
+ sock = nil
450
+ end
451
+ @mutex_sock.delete(sock.object_id)
460
452
  end
461
453
  end # mutex_proc_thread
462
454
 
@@ -465,6 +457,34 @@ EOF
465
457
 
466
458
  end
467
459
 
460
+ # Flashのポリシーファイルの処理
461
+ def do_flash_policy_file(sid, sock)
462
+ logger.debug "is_flash_policy_file"
463
+
464
+ if @policy_file_request # ポリシーファイルを返す設定なら
465
+ logger.info "is_flash_policy_file #{sid} #{@policy_file_request}"
466
+
467
+ allow_str = ""
468
+
469
+ @policy_file_allow_domain.each do |one_host|
470
+ allow_str += %Q|<allow-access-from domain="#{one_host}" to-ports="#{@policy_file_allow_port.join(',')}" />|
471
+ allow_str += "\n"
472
+ end
473
+
474
+ policy_data = <<EOF
475
+ <?xml version="1.0"?>
476
+ <cross-domain-policy>
477
+ #{allow_str}
478
+ </cross-domain-policy>
479
+ EOF
480
+
481
+ logger.debug policy_data
482
+ sock.write policy_data
483
+ sock.flush
484
+ logger.info "policy file sent."
485
+ end
486
+ end
487
+
468
488
  # action_nameが送信パケットの返事なら
469
489
  def action_name_is_response(ret_obj)
470
490
  logger.debug "action_name_is_response: #{ret_obj['_id'].inspect} #{session[:sid].inspect}"
@@ -511,12 +531,12 @@ EOF
511
531
  @policy_file_allow_port = @config['server']['policy_file_allow_port']
512
532
  @policy_file_allow_port = [@network_port] if !@policy_file_allow_port
513
533
 
514
- @safe_resolver = @config['server']['safe_resolver'] || false # require 'resolv-replace'するかどうか
534
+ @safe_resolver = @config['server']['safe_resolver'] || false # require 'resolv-replace'するかどうか
515
535
 
516
- @statistics_process_memory = @config['server']['statistics_process_memory'] || false # プロセスのメモリ使用量統計を取る
536
+ @statistics_process_memory = @config['server']['statistics_process_memory'] || false # プロセスのメモリ使用量統計取る
517
537
 
518
- @backdoor_run_drb_server = @config['server']['backdoor_run_drb_server'] || false # バックドア用のdrbサーバーを起動するかどうか
519
- @backdoor_run_drb_port = @config['server']['backdoor_run_drb_port'] || 12345 # バックドア用のdrbサーバーのポート番号
538
+ @backdoor_run_drb_server = @config['server']['backdoor_run_drb_server'] || false # drbサーバーを起動するか
539
+ @backdoor_run_drb_port = @config['server']['backdoor_run_drb_port'] || 12345 # drbサーバーのポート番号
520
540
  @backdoor_host = @config['server']['backdoor_host'] || '127.0.0.1' # バックドアのアクセス可能ホスト名
521
541
 
522
542
  @loop_setting = @config['server']['loop_setting'] # メインループ用の定義
@@ -625,25 +645,7 @@ EOF
625
645
  logger.debug "GC end #{Time.now - gc_start_time}sec "
626
646
  # Thread.critical = false
627
647
 
628
- # メモリ使用量統計
629
- if @statistics_process_memory
630
- memory_usage = 0
631
- if RUBY_PLATFORM == 'i386-mswin32'
632
- require "win32ole"
633
- locator = WIN32OLE.new("WbemScripting.SWbemLocator.1") #(A)
634
- service = locator.ConnectServer #(B)
635
- set = service.ExecQuery("select * from Win32_Process WHERE ProcessId = #{Process.pid}") #(C)
636
- set.each do |process|
637
- memory_usage = process.PageFileUsage.to_i
638
- end
639
- else
640
- stat = `cat /proc/#{Process.pid}/stat`.split(" ")
641
- memory_usage = stat[22].to_i
642
- end
643
-
644
- 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" }
645
- logger.debug "statistics_process_memory file add."
646
- end
648
+ output_memory_statistics() if @statistics_process_memory # メモリ使用量統計
647
649
 
648
650
  rescue Exception
649
651
  logger.error "Exception gc_thread_start #{error_message($!, 'u')}"
@@ -653,6 +655,29 @@ EOF
653
655
  th.priority = 3
654
656
  end
655
657
 
658
+ # メモリ使用量統計
659
+ def output_memory_statistics()
660
+ memory_usage = 0
661
+ if RUBY_PLATFORM == 'i386-mswin32'
662
+ require "win32ole"
663
+ locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
664
+ service = locator.ConnectServer
665
+ set = service.ExecQuery("select * from Win32_Process WHERE ProcessId = #{Process.pid}")
666
+ set.each do |process|
667
+ memory_usage = process.PageFileUsage.to_i
668
+ end
669
+ else
670
+ stat = `cat /proc/#{Process.pid}/stat`.split(" ")
671
+ memory_usage = stat[22].to_i
672
+ end
673
+
674
+ open("log/dango_stat_proc_mem_#{RAILS_ENV}.log", "ab") do |fh|
675
+ fh.write "#{Time.now_to_s},#{memory_usage},#{@thr_gr_gserver_serve.list.length}\n"
676
+ end
677
+ logger.debug "statistics_process_memory file add."
678
+ end
679
+
680
+
656
681
  # ハートビートスレッドの開始
657
682
  def heart_beat_thread_start
658
683
  shared[:_heart_beat_time_hash] = {}
@@ -663,38 +688,41 @@ EOF
663
688
  begin
664
689
  sleep @herat_beat_interval_sec
665
690
 
666
- if ! @gserver.stopped? # gserverが起動していれば
667
- logger.debug "heart_beat_thread_start "
691
+ next if @gserver.stopped? # gserverが起動していればスキップ
692
+
693
+ logger.debug "heart_beat_thread_start "
694
+
695
+ @mutex_proc_thread.synchronize do
696
+ # クライアントから来るハートビートのチェック
697
+ heart_beat_time_hash = shared[:_heart_beat_time_hash]
668
698
 
669
- @mutex_proc_thread.synchronize do
670
- # クライアントから来るハートビートのチェック
671
- heart_beat_time_hash = shared[:_heart_beat_time_hash]
699
+ # 全員分のチェック
700
+ socket_list.all_sid.each do |sid|
701
+ sock = socket_list[sid]
672
702
 
673
- # 全員分のチェック
674
- socket_list.all_sid.each do |sid|
675
- sock = socket_list[sid]
676
-
677
- if ! sock # すでにsocketが無い場合は、スキップ
678
- logger.warn "!!!! heart_beat_thread_start:sock is not found. #{sid}:#{sock}"
679
- next
680
- end
681
-
682
- # クライアントから来たハートビートの時間チェックし、古ければsocketを閉じる
683
- if heart_beat_time_hash[sid] && heart_beat_time_hash[sid] < Time.now - @heart_beat_receive_wait_sec
684
- logger.warn "!!!! heart_beat_thread_start:heart beat old:#{sid}:#{heart_beat_time_hash[sid]}:#{sock}:#{sock.closed?}"
685
- # sock.close if !sock.closed?
686
- begin
703
+ if ! sock # すでにsocketが無い場合は、スキップ
704
+ logger.warn "!!!! heart_beat_thread_start:sock is not found. #{sid}:#{sock}"
705
+ next
706
+ end
707
+
708
+ # クライアントから来たハートビートの時間チェックし、古ければsocketを閉じる
709
+ if heart_beat_time_hash[sid] &&
710
+ heart_beat_time_hash[sid] < Time.now - @heart_beat_receive_wait_sec
711
+ logger.warn "!!!! heart_beat_thread_start:heart beat old:#{sid}:" +
712
+ "#{heart_beat_time_hash[sid]}:#{sock}:#{sock.closed?}"
713
+ begin
714
+ @mutex_sock[sock.object_id].synchronize do
687
715
  sock.close
688
- rescue IOError
689
- logger.debug "heart_beat_thread_start:maybe already closed. IOError:#{sid}:#{sock}"
690
- rescue
691
- logger.warn "heart_beat_thread_start:failed close socket:#{error_message($!, 'u')}"
692
- end
693
- next
716
+ end # @mutex_sock[sock.object_id].synchronize
717
+ rescue IOError
718
+ logger.debug "heart_beat_thread_start:maybe already closed. IOError:#{sid}:#{sock}"
719
+ rescue
720
+ logger.warn "heart_beat_thread_start:failed close socket:#{error_message($!, 'u')}"
694
721
  end
722
+ next
695
723
  end
696
- end # @mutex_proc_thread
697
- end # ! @gserver.stopped?
724
+ end # socket_list
725
+ end # @mutex_proc_thread
698
726
 
699
727
  # # スレッド情報をログに出力
700
728
  # if logger.debug?
@@ -802,6 +830,7 @@ EOF
802
830
  # sidごとにデータをまとめ送り
803
831
  send_data_sid_list.each do |sid, one_send_data_list|
804
832
  sock = socket_list[sid]
833
+
805
834
  if !sock
806
835
  logger.info "thread_send_notice_queue:not found sid=#{sid} sock=#{sock.inspect}"
807
836
  next
@@ -813,11 +842,12 @@ EOF
813
842
  end
814
843
 
815
844
  begin
816
- logger.debug "thread_send_notice_queue:dango_send_data:sid=#{sid} sock=#{sock.inspect} #{one_send_data_list.collect{|d| d['_notice_name'] + ','}}"
817
- # logger.debug "thread_send_notice_queue:one_send_data_list=#{one_send_data_list.inspect}"
818
- # logger.debug one_send_data_list.pretty_inspect
845
+ logger.debug "thread_send_notice_queue:dango_send_data:sid=#{sid} sock=#{sock.inspect} " +
846
+ "#{one_send_data_list.collect{|d| d['_notice_name'] + ','}}"
819
847
 
820
- dango_send_data(sock, one_send_data_list, :type=>send_data_encode_type_list[sid]) # データ送信
848
+ @mutex_sock[sock.object_id].synchronize do
849
+ dango_send_data(sock, one_send_data_list, :type=>send_data_encode_type_list[sid]) # データ送信
850
+ end # mutex_sock[sock.object_id].synchronize
821
851
 
822
852
  rescue DangoFrameworkConnectionException
823
853
  logger.info "thread_send_notice_queue:failed send. sid=#{sid} sock=#{sock.inspect} #{$!.class}"
@@ -4,13 +4,14 @@
4
4
  class SessionManager
5
5
  MaxSidCounter = 999999
6
6
 
7
- def initialize(shared)
7
+ def initialize(shared, rails_env)
8
8
  @shared = shared
9
+ @rails_env = rails_env
10
+
9
11
  @session_list = {}
10
12
  @session_mutex = Mutex.new
11
13
 
12
14
  @shared[:_session_manager] = {}
13
-
14
15
  end
15
16
 
16
17
 
@@ -26,7 +27,8 @@ class SessionManager
26
27
  def close_session(sid)
27
28
  @session_mutex.synchronize do
28
29
  drop_sid()
29
- @session_list[Thread.current.object_id] = nil
30
+ # @session_list[Thread.current.object_id] = nil
31
+ @session_list.delete(Thread.current.object_id)
30
32
  end
31
33
  end
32
34
 
@@ -54,9 +56,8 @@ class SessionManager
54
56
  sid = ses_man[:sid_counter] if ! ses_man[:sid_list].has_key?(ses_man[:sid_counter])
55
57
  end
56
58
 
57
- ses_man[:sid_list][ses_man[:sid_counter]] = "#{Process.pid}:#{Thread.current.object_id}"
59
+ ses_man[:sid_list][sid] = "#{@rails_env}:#{Process.pid}:#{Thread.current.object_id}"
58
60
 
59
- ses_man
60
61
  @shared.commit(ses_man)
61
62
  end
62
63
 
@@ -68,9 +69,8 @@ class SessionManager
68
69
  @shared.transaction(:_session_manager) do |ses_man|
69
70
 
70
71
  # ses_man[:sid_list].delete(sid)
71
- ses_man[:sid_list].delete_if{|sid, oid| oid == "#{Process.pid}:#{Thread.current.object_id}" }
72
+ ses_man[:sid_list].delete_if{|sid, oid| oid == "#{@rails_env}:#{Process.pid}:#{Thread.current.object_id}" }
72
73
 
73
- ses_man
74
74
  @shared.commit(ses_man)
75
75
  end
76
76
 
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 = 4
5
- TINY = 3
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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.4.3
4
+ version: 0.4.5
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-09-25 00:00:00 +09:00
12
+ date: 2008-10-04 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -28,9 +28,9 @@ dependencies:
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.0
33
+ version: 0.4.5
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: hoe