dango 0.4.0 → 0.4.1

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.
@@ -58,6 +58,7 @@ class DangoFrameworkDisconnectException < DangoFrameworkException; end
58
58
  class DangoFrameworkReadNoDataException < DangoFrameworkException; end
59
59
  class DangoFrameworkFlashPolicyException < DangoFrameworkException; end
60
60
  class DangoFrameworkMonitorSecurityException < DangoFrameworkException; end
61
+ class DangoFrameworkTransactionException < DangoFrameworkException; end
61
62
 
62
63
  # エラー出力用モジュール
63
64
  module ErrorMessage
@@ -9,7 +9,6 @@ require 'digest/md5'
9
9
  require "dango/framework_base"
10
10
  require "dango/socket_list"
11
11
  require "dango/version"
12
- require "dango/mutex_socket_list"
13
12
  require "dango/session_manager"
14
13
  require "dango/monitor/server_monitor_action"
15
14
 
@@ -51,12 +50,12 @@ class DangoServerFramework
51
50
  def stop_gserver() # gserverの停止
52
51
  if @gserver && !@gserver.stopped?
53
52
  # 強制的に接続しているsocketをクローズ
54
- logger.info "socket_list.keys:#{socket_list.keys.inspect}"
55
- socket_list.keys.each do |sk|
56
- logger.debug "sk:#{socket_list[sk].inspect}"
57
- next if ! socket_list[sk]
58
- socket_list[sk].close if ! socket_list[sk].closed?
59
- socket_list[sk]
53
+ logger.info "socket_list.all_sid:#{socket_list.all_sid.inspect}"
54
+ socket_list.all_sid.each do |sid|
55
+ logger.debug "sk:#{socket_list[sid].inspect}"
56
+ next if ! socket_list[sid]
57
+ socket_list[sid].close if ! socket_list[sid].closed?
58
+ socket_list[sid]
60
59
  end
61
60
 
62
61
  # サーバーを停止
@@ -144,24 +143,24 @@ class DangoServerFramework
144
143
  logger.warn("Process.pid=#{Process.pid}")
145
144
  logger.warn("Dango Version=#{Dango::VERSION::STRING}")
146
145
  # logger.debug("$LOADED_FEATURES=#{$LOADED_FEATURES.pretty_inspect}")
147
-
148
- @session_manager = SessionManager.new # セッション情報の初期化
149
- shared_init() # 共有メモリを初期化
150
- socket_list_init() # ソケット一覧を初期化
151
- mutex_socket_list_init() # ソケット毎用のmutexを初期化
152
- @mutex_proc_thread = Mutex.new # スレッドが同時起動しないようにするためのMutex
153
- heart_beat_thread_start() # ハートビートスレッドの開始
154
- gc_thread_start() # GCスレッドの開始
155
-
156
- dango_server_init() # 初期設定読み込み
157
-
158
- @mutex_send_response = Mutex.new # 送信レスポンス用のMutex
159
- @arr_send_response = [] # 送信レスポンス用のキャッシュ
146
+
147
+ shared_init() # 共有メモリを初期化
148
+ socket_list_init() # ソケット一覧を初期化
149
+ @session_manager = SessionManager.new(shared) # セッション情報の初期化
150
+ @mutex_proc_thread = Mutex.new # スレッドが同時起動しないようにするためのMutex
151
+ heart_beat_thread_start() # ハートビートスレッドの開始
152
+ gc_thread_start() # GCスレッドの開始
153
+
154
+ dango_server_init() # 初期設定読み込み
155
+
156
+ @mutex_send_response = Mutex.new # 送信レスポンス用のMutex
157
+ @arr_send_response = [] # 送信レスポンス用のキャッシュ
158
+
160
159
 
161
160
  TCPSocket.do_not_reverse_lookup = true # 逆引きを行わない
162
161
  # TCPSocket.do_not_reverse_lookup = false # 逆引きを行う
163
162
 
164
- if @backdoor_run_drb_server # backdoor用のdrbを起動
163
+ if @backdoor_run_drb_server # backdoor用のdrbを起動
165
164
  uri = "druby://#{@network_host}:#{@backdoor_run_drb_port}"
166
165
  DRb.start_service(uri, self)
167
166
  logger.warn("start drb server: uri=#{DRb.uri}")
@@ -283,7 +282,6 @@ class DangoServerFramework
283
282
  logger.debug "thread_main:start_session. sid=#{sid} sock=#{sock} thread.current=#{Thread.current.object_id}"
284
283
 
285
284
  socket_list.add(sid, sock)
286
- mutex_socket_list.add(sid)
287
285
 
288
286
  session[:connected] = nil # まだdango_connectを呼び出していない
289
287
 
@@ -574,12 +572,6 @@ EOF
574
572
  end
575
573
  attr_accessor(:socket_list)
576
574
 
577
- # ソケット毎用のmutex
578
- def mutex_socket_list_init()
579
- @mutex_socket_list = MutexSocketList.new() # ソケット毎用のmutex
580
- end
581
- attr_accessor(:mutex_socket_list)
582
-
583
575
 
584
576
  # 接続時に呼び出されるメソッド
585
577
  def dango_connect
@@ -667,7 +659,7 @@ EOF
667
659
  heart_beat_time_hash = shared[:_heart_beat_time_hash]
668
660
 
669
661
  # 全員分のチェック
670
- socket_list.keys.each do |sid|
662
+ socket_list.all_sid.each do |sid|
671
663
  sock = socket_list[sid]
672
664
 
673
665
  if ! sock # すでにsocketが無い場合は、スキップ
@@ -694,7 +686,7 @@ EOF
694
686
  if logger.debug?
695
687
  count += 1
696
688
  if count % 100 == 0
697
- sids = socket_list.keys
689
+ sids = socket_list.all_sid
698
690
  thr_list = @thr_gr_gserver_serve.list.collect{|th| th.object_id }
699
691
 
700
692
  logger.debug "heart_beat_thread_start:sids=#{sids.inspect}"
@@ -719,6 +711,7 @@ EOF
719
711
  shared.transaction(:_heart_beat_time_hash) do |heart_beat_time_hash|
720
712
  heart_beat_time_hash[session[:sid]] = Time.now
721
713
  heart_beat_time_hash
714
+ shared.commit(heart_beat_time_hash)
722
715
  end
723
716
  end
724
717
 
@@ -4,12 +4,13 @@
4
4
  class SessionManager
5
5
  MaxSidCounter = 999999
6
6
 
7
- def initialize
7
+ def initialize(shared)
8
+ @shared = shared
8
9
  @session_list = {}
9
10
  @session_mutex = Mutex.new
10
11
 
11
- @sid_counter = 0
12
- @sid_list = {}
12
+ @shared[:_session_manager] = {}
13
+
13
14
  end
14
15
 
15
16
 
@@ -22,7 +23,7 @@ class SessionManager
22
23
  end
23
24
 
24
25
  # session終了
25
- def close_session()
26
+ def close_session(sid)
26
27
  @session_mutex.synchronize do
27
28
  drop_sid()
28
29
  @session_list[Thread.current.object_id] = nil
@@ -42,19 +43,37 @@ class SessionManager
42
43
  # sid情報作成
43
44
  def generate_sid()
44
45
  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)
46
+ @shared.transaction(:_session_manager) do |ses_man|
47
+
48
+ ses_man[:sid_counter] = 0 if ! ses_man[:sid_counter]
49
+ ses_man[:sid_list] = {} if ! ses_man[:sid_list]
50
+
51
+ while(sid == nil) do
52
+ ses_man[:sid_counter] += 1
53
+ ses_man[:sid_counter] = 1 if ses_man[:sid_counter] > MaxSidCounter
54
+ sid = ses_man[:sid_counter] if ! ses_man[:sid_list].has_key?(ses_man[:sid_counter])
55
+ end
56
+
57
+ ses_man[:sid_list][ses_man[:sid_counter]] = "#{Process.pid}:#{Thread.current.object_id}"
58
+
59
+ ses_man
60
+ @shared.commit(ses_man)
49
61
  end
50
62
 
51
- @sid_list[sid] = Thread.current.object_id
52
63
  sid
53
64
  end
54
65
 
55
66
  # sid削除
56
67
  def drop_sid()
57
- @sid_list.delete_if{|sid, oid| oid == Thread.current.object_id }
68
+ @shared.transaction(:_session_manager) do |ses_man|
69
+
70
+ # ses_man[:sid_list].delete(sid)
71
+ ses_man[:sid_list].delete_if{|sid, oid| oid == "#{Process.pid}:#{Thread.current.object_id}" }
72
+
73
+ ses_man
74
+ @shared.commit(ses_man)
75
+ end
76
+
58
77
  self
59
78
  end
60
79
 
@@ -13,12 +13,19 @@ module DangoFrameworkModule
13
13
  @data = {}
14
14
  @mutex = {}
15
15
  @size = 0
16
+
17
+ @transact_key = {}
18
+ @transact_thread = {}
19
+ @transact_commit = {}
20
+ @transact_rollback = {}
21
+ @transact_data = {}
16
22
  end
17
23
 
18
24
  def keys
19
25
  @data.keys
20
26
  end
21
27
 
28
+ # ハッシュ形式で取得
22
29
  def to_hash
23
30
  hash = {}
24
31
  @data.each do |k, v|
@@ -27,18 +34,106 @@ module DangoFrameworkModule
27
34
  hash
28
35
  end
29
36
 
30
- def transaction(key) # トランザクション処理ブロックを作る
37
+ =begin
38
+ # 昔のトランザクション処理ロジック
39
+ def transaction(key)
31
40
  key = key.to_s
32
41
  if !@mutex.has_key?(key) # 未定義キーならエラー
33
42
  raise(DangoFrameworkException, "Shared key is not exist.")
34
43
  end
44
+
35
45
  @mutex[key].synchronize do
36
46
  # data = yield(@data[key].deep_dup)
37
47
  data = yield(@data[key])
38
48
  @data[key] = data.deep_dup
39
49
  end
50
+
51
+ self
52
+ end
53
+ def commit(key, value) # トランザクションのコミット処理
54
+ value
55
+ end
56
+ def rollback(key) # トランザクションのロールバック処理
57
+ end
58
+ =end
59
+
60
+ # トランザクション処理ブロックを作る(key単位のロック)
61
+ # このブロックの中でcommitかrollbackか例外発生を行わなければならない
62
+ def transaction(key)
63
+ key = key.to_s
64
+ if !@mutex.has_key?(key) # 未定義キーならエラー
65
+ raise(DangoFrameworkException, "Shared key is not exist.")
66
+ end
67
+
68
+ @mutex[key].synchronize do
69
+ @transact_key[Thread.current] = key # 違うスレッドからcommitできないように
70
+
71
+ raise("nested transaction #{key}") if @transact_thread.has_key?(key)
72
+ @transact_thread[key] = Thread.current
73
+ @transact_commit[key] = false
74
+ @transact_rollback[key] = false
75
+ @transact_data[key] = nil
76
+
77
+ begin
78
+ catch(:memory_store_finish_transaction) do
79
+ yield(@data[key].deep_dup)
80
+ end
81
+ rescue Exception # 例外発生の場合はrollbackとみなして、直前のエラーを再発生
82
+ @transact_rollback[key] = true
83
+ raise
84
+ ensure
85
+ @transact_thread.delete(key)
86
+
87
+ if @transact_commit[key] # commitされた場合 データ書き込み
88
+ @data[key] = @transact_data[key].deep_dup
89
+
90
+ elsif @transact_rollback[key] # rollbackがあった場合 何もしない
91
+
92
+ else # commitもrollbackもしていなければ
93
+ raise(DangoFrameworkTransactionException, "not found commit and rollback in transaction")
94
+ end
95
+
96
+ @transact_commit.delete(key)
97
+ @transact_rollback.delete(key)
98
+ @transact_data.delete(key)
99
+
100
+ @transact_key.delete(Thread.current)
101
+ end
102
+ end
103
+
104
+ self
105
+ end
106
+
107
+ def commit(value) # トランザクションのコミット処理
108
+ if ! @transact_key.has_key?(Thread.current)
109
+ raise(DangoFrameworkTransactionException, "this thread has not transaction #{Thread.current}")
110
+ end
111
+ key = @transact_key[Thread.current]
112
+
113
+ if @transact_thread[key] != Thread.current
114
+ raise(DangoFrameworkTransactionException, "not in transaction #{key}")
115
+ end
116
+
117
+ @transact_commit[key] = true
118
+ @transact_data[key] = value
119
+ throw(:memory_store_finish_transaction)
40
120
  end
41
121
 
122
+ def rollback() # トランザクションのロールバック処理
123
+ if ! @transact_key.has_key?(Thread.current)
124
+ raise(DangoFrameworkTransactionException, "this thread has not transaction #{Thread.current}")
125
+ end
126
+ key = @transact_key[Thread.current]
127
+
128
+ if @transact_thread[key] != Thread.current
129
+ raise(DangoFrameworkTransactionException, "not in transaction #{key}")
130
+ end
131
+
132
+ @transact_rollback[key] = true
133
+ throw(:memory_store_finish_transaction)
134
+ end
135
+
136
+
42
137
  def has_key?(key) # キーがあるかどうかを返す
43
138
  key = key.to_s
44
139
  @data.has_key?(key)
@@ -51,10 +146,13 @@ module DangoFrameworkModule
51
146
  # raise(DangoFrameworkException, "Shared key is not exist.")
52
147
  end
53
148
 
54
- @data[key].deep_dup
149
+ # @mutex[key].synchronize do
150
+ @data[key].deep_dup
151
+ # end
55
152
  end
56
153
 
57
154
  def []=(key, value)
155
+ key = key.to_s
58
156
  # キーはString Symbolのみ
59
157
  if key.class != String && key.class != Symbol
60
158
  raise(DangoFrameworkException, "Shared key is not String or Symbol.")
@@ -72,7 +170,7 @@ module DangoFrameworkModule
72
170
  @data[key] = value.deep_dup
73
171
  end
74
172
 
75
- nil
173
+ value
76
174
  end
77
175
  end
78
176
 
@@ -7,39 +7,31 @@ class SocketList
7
7
  @sl_mutex = Mutex.new
8
8
  end
9
9
 
10
- def keys()
10
+ def all_sid()
11
11
  @sl_mutex.synchronize do
12
12
  @sl_hash.keys
13
13
  end
14
14
  end
15
15
 
16
- def delete(key)
16
+ def delete(sid)
17
17
  @sl_mutex.synchronize do
18
- @sl_hash.delete(key)
18
+ @sl_hash.delete(sid)
19
19
  end
20
20
  end
21
21
 
22
- def add(key, sock)
22
+ def add(sid, sock)
23
23
  @sl_mutex.synchronize do
24
- raise("already exist key(#{key.inspect})") if @sl_hash.has_key?(key)
24
+ raise("already exist sid(#{sid.inspect})") if @sl_hash.has_key?(sid)
25
25
  raise("sock(#{sock.inspect}) is not Socket") if sock.kind_of?(Socket)
26
- @sl_hash[key] = sock
26
+ @sl_hash[sid] = sock
27
27
  end
28
28
  end
29
29
 
30
- def [](key)
30
+ def [](sid)
31
31
  @sl_mutex.synchronize do
32
- # raise("not exist key(#{key.inspect})") if ! @sl_hash.has_key?(key)
33
- return(nil) if ! @sl_hash.has_key?(key)
34
- @sl_hash[key]
35
- end
36
- end
37
-
38
- def []=(key, sock)
39
- @sl_mutex.synchronize do
40
- # raise("not exist key(#{key.inspect})") if ! @sl_hash.has_key?(key)
41
- raise("sock(#{sock.inspect}) is not Socket") if sock.kind_of?(Socket)
42
- @sl_hash[key] = sock
32
+ # raise("not exist sid(#{sid.inspect})") if ! @sl_hash.has_key?(sid)
33
+ return(nil) if ! @sl_hash.has_key?(sid)
34
+ @sl_hash[sid]
43
35
  end
44
36
  end
45
37
  end
@@ -218,6 +218,7 @@ class TestClient < DangoClientFramework
218
218
  send_receive_shared.transaction(:receive_cache) do |receive_cache|
219
219
  receive_cache.push([name, ret_obj, Time.now])
220
220
  receive_cache
221
+ send_receive_shared.commit(receive_cache)
221
222
  end
222
223
 
223
224
  else
@@ -269,14 +270,18 @@ class TestClient < DangoClientFramework
269
270
  send_receive_shared.transaction(:receive_cache) do |receive_cache|
270
271
  receive_cache.delete_at(receive_idx)
271
272
  receive_cache
273
+ send_receive_shared.commit(receive_cache)
272
274
  end
273
275
 
274
276
  # 古いreceive_cacheを削除しておく
275
277
  send_receive_shared.transaction(:receive_cache) do |receive_cache|
276
- receive_cache.select do |one_receive_cache|
278
+ receive_cache = receive_cache.select do |one_receive_cache|
277
279
  # true
278
280
  one_receive_cache[2] > Time.now - @receive_cache_auto_delete_sec
279
281
  end
282
+
283
+ receive_cache
284
+ send_receive_shared.commit(receive_cache)
280
285
  end
281
286
 
282
287
  receive_data[1]
@@ -292,6 +297,7 @@ class TestClient < DangoClientFramework
292
297
  true if (! notice_name) || (notice_name && one_rec_data[0] == notice_name)
293
298
  end
294
299
  receive_cache
300
+ send_receive_shared.commit(receive_cache)
295
301
  end
296
302
  end
297
303
 
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 = 0
5
+ TINY = 1
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.0
4
+ version: 0.4.1
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-11 00:00:00 +09:00
12
+ date: 2008-09-17 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -57,7 +57,6 @@ files:
57
57
  - lib/dango/client_framework.rb
58
58
  - lib/dango/framework_base.rb
59
59
  - lib/dango/server_framework.rb
60
- - lib/dango/mutex_socket_list.rb
61
60
  - lib/dango/socket_list.rb
62
61
  - lib/dango/session_manager.rb
63
62
  - lib/dango/dango_g_server.rb
@@ -1,35 +0,0 @@
1
- #!ruby -Ku
2
-
3
- # ソケット毎用のmutex
4
- class MutexSocketList
5
- def initialize()
6
- @msl_hash = Hash.new
7
- end
8
-
9
- def keys()
10
- @msl_hash.keys
11
- end
12
-
13
- def delete(key)
14
- @msl_hash.delete(key)
15
- end
16
-
17
- def add(key)
18
- @msl_hash[key] = Mutex.new
19
- end
20
-
21
- # def [](key)
22
- # raise("not exist key(#{key})") if ! @msl_hash.has_key?(key)
23
- # add(key) if @msl_hash.has_key?(key)
24
- # @msl_hash[key]
25
- # end
26
-
27
- def synchronize(key)
28
- raise("not exist key(#{key})") if ! @msl_hash.has_key?(key)
29
- ret = nil
30
- @msl_hash[key].synchronize do
31
- ret = yield
32
- end
33
- ret
34
- end
35
- end