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.
- data/lib/dango/framework_base.rb +1 -0
- data/lib/dango/server_framework.rb +23 -30
- data/lib/dango/session_manager.rb +29 -10
- data/lib/dango/shared/memory_store.rb +101 -3
- data/lib/dango/socket_list.rb +10 -18
- data/lib/dango/tester/dango_tester_client.rb +7 -1
- data/lib/dango/version.rb +1 -1
- metadata +2 -3
- data/lib/dango/mutex_socket_list.rb +0 -35
data/lib/dango/framework_base.rb
CHANGED
@@ -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.
|
55
|
-
socket_list.
|
56
|
-
logger.debug "sk:#{socket_list[
|
57
|
-
next if ! socket_list[
|
58
|
-
socket_list[
|
59
|
-
socket_list[
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
@
|
159
|
-
|
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
|
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.
|
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.
|
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
|
-
@
|
12
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
@
|
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
|
-
|
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
|
-
@
|
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
|
-
|
173
|
+
value
|
76
174
|
end
|
77
175
|
end
|
78
176
|
|
data/lib/dango/socket_list.rb
CHANGED
@@ -7,39 +7,31 @@ class SocketList
|
|
7
7
|
@sl_mutex = Mutex.new
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
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(
|
16
|
+
def delete(sid)
|
17
17
|
@sl_mutex.synchronize do
|
18
|
-
@sl_hash.delete(
|
18
|
+
@sl_hash.delete(sid)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def add(
|
22
|
+
def add(sid, sock)
|
23
23
|
@sl_mutex.synchronize do
|
24
|
-
raise("already exist
|
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[
|
26
|
+
@sl_hash[sid] = sock
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def [](
|
30
|
+
def [](sid)
|
31
31
|
@sl_mutex.synchronize do
|
32
|
-
# raise("not exist
|
33
|
-
return(nil) if ! @sl_hash.has_key?(
|
34
|
-
@sl_hash[
|
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
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.
|
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-
|
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
|