dango 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|