dango 0.4.8 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dango/client_framework.rb +13 -12
- data/lib/dango/controller_plugin/dango_controller_plugin.rb +7 -3
- data/lib/dango/dango_g_server.rb +7 -6
- data/lib/dango/dango_logger.rb +115 -0
- data/lib/dango/dango_mutex.rb +64 -0
- data/lib/dango/default_dango_receive.rb +140 -0
- data/lib/dango/error_message.rb +30 -0
- data/lib/dango/framework_base.rb +112 -79
- data/lib/dango/monitor/server_monitor_module.rb +131 -0
- data/lib/dango/server_framework.rb +215 -145
- data/lib/dango/session_manager.rb +15 -10
- data/lib/dango/shared/memory_store.rb +10 -10
- data/lib/dango/socket_list.rb +5 -5
- data/lib/dango/tasks/dango_rake.rb +379 -166
- data/lib/dango/tester/dango_tester_client.rb +1 -6
- data/lib/dango/version.rb +2 -2
- metadata +8 -3
@@ -73,7 +73,8 @@ class DangoClientFramework
|
|
73
73
|
@log_shift_age = @connection_client_log_shift_age
|
74
74
|
|
75
75
|
# loggerの準備
|
76
|
-
logger.
|
76
|
+
logger.info("-------client initialize")
|
77
|
+
logger.info("host=#{@connection_client_host} port=#{@connection_client_port}")
|
77
78
|
logger.info("@log_file = #{@log_file}")
|
78
79
|
logger.info("@log_level = #{@log_level}")
|
79
80
|
logger.info("@log_max_size = #{@log_max_size}")
|
@@ -81,7 +82,7 @@ class DangoClientFramework
|
|
81
82
|
|
82
83
|
# データ送受信用の共有メモリ初期化
|
83
84
|
send_return_shared_init()
|
84
|
-
@send_receive_mutex =
|
85
|
+
@send_receive_mutex = DangoMutex.new(:send_receive_mutex) # 送受信用の排他処理
|
85
86
|
|
86
87
|
# 通知共有メモリの初期化
|
87
88
|
dango_client_notice_shared_init()
|
@@ -101,7 +102,7 @@ class DangoClientFramework
|
|
101
102
|
@sock.sync = true
|
102
103
|
logger.debug("addr:#{@sock.addr.inspect}")
|
103
104
|
|
104
|
-
@tmutex =
|
105
|
+
@tmutex = DangoMutex.new(:tmutex) # sockの排他処理用
|
105
106
|
|
106
107
|
dango_heart_beat_thread_init() # ハートビート送信スレッドの起動
|
107
108
|
|
@@ -150,12 +151,12 @@ class DangoClientFramework
|
|
150
151
|
__send__("dango_receive_#{notice_name}", ret_obj)
|
151
152
|
rescue
|
152
153
|
logger.error "error in dango_receive_#{notice_name} #{@sid} \n#{error_message($!, 'u')}"
|
153
|
-
ensure
|
154
|
-
# データの受信の送信返し
|
155
|
-
response_notice_name = "_response"
|
156
|
-
send_obj = {"_id" => ret_obj["_id"]}
|
157
|
-
send_action(response_notice_name, send_obj)
|
158
|
-
logger.debug "response_notice_name=#{response_notice_name.inspect} #{@sid} "
|
154
|
+
# ensure
|
155
|
+
# # データの受信の送信返し
|
156
|
+
# response_notice_name = "_response"
|
157
|
+
# send_obj = {"_id" => ret_obj["_id"]}
|
158
|
+
# send_action(response_notice_name, send_obj)
|
159
|
+
# logger.debug "response_notice_name=#{response_notice_name.inspect} #{@sid} "
|
159
160
|
end
|
160
161
|
logger.debug "called method=#{notice_name.inspect} #{@sid} "
|
161
162
|
end
|
@@ -243,7 +244,7 @@ class DangoClientFramework
|
|
243
244
|
def dango_client_send_encrypt(str) # 継承用
|
244
245
|
str
|
245
246
|
end
|
246
|
-
def
|
247
|
+
def send_encrypt(str) # フレームワークから呼ばれる部分
|
247
248
|
dango_client_send_encrypt(str)
|
248
249
|
end
|
249
250
|
|
@@ -251,7 +252,7 @@ class DangoClientFramework
|
|
251
252
|
def dango_client_receive_decrypt(str) # 継承用
|
252
253
|
str
|
253
254
|
end
|
254
|
-
def
|
255
|
+
def receive_decrypt(str) # フレームワークから呼ばれる部分
|
255
256
|
dango_client_receive_decrypt(str)
|
256
257
|
end
|
257
258
|
|
@@ -275,7 +276,7 @@ class DangoClientFramework
|
|
275
276
|
return_name = options[:return_name] || ("return_" + action_name.to_s).to_sym
|
276
277
|
timeout = options[:timeout] || 6
|
277
278
|
|
278
|
-
@send_receive_mutex.
|
279
|
+
@send_receive_mutex.timeout_sync(10, :send_return) do
|
279
280
|
send_return_shared[action_name] = nil
|
280
281
|
|
281
282
|
receive_thread = nil
|
@@ -4,6 +4,7 @@
|
|
4
4
|
= Dangoサーバーのメンテナンス用モニタ
|
5
5
|
=end
|
6
6
|
|
7
|
+
require "timeout"
|
7
8
|
|
8
9
|
# モニター用のdangoクライアントクラス
|
9
10
|
module DangoControllerPlugin
|
@@ -18,10 +19,13 @@ module DangoControllerPlugin
|
|
18
19
|
def self.dango_server_call(method_name, arg, options = {})
|
19
20
|
config = dango_server_config(options)
|
20
21
|
raise("backdoor_run_drb_server is false.") if !config['server']['backdoor_run_drb_server']
|
21
|
-
drb_uri = "druby://#{config['network']['host']}:#{config['server']['backdoor_run_drb_port']}"
|
22
|
+
# drb_uri = "druby://#{config['network']['host']}:#{config['server']['backdoor_run_drb_port']}"
|
23
|
+
drb_uri = config['server']['backdoor_run_drb_url']
|
22
24
|
begin
|
23
|
-
|
24
|
-
|
25
|
+
timeout(3) do
|
26
|
+
drb_obj = DRbObject.new_with_uri(drb_uri)
|
27
|
+
drb_obj.__send__(method_name.to_s, arg)
|
28
|
+
end
|
25
29
|
rescue Exception
|
26
30
|
raise("DRbError:#{$!.class} #{$!.message} #{$!.backtrace.inspect}")
|
27
31
|
end
|
data/lib/dango/dango_g_server.rb
CHANGED
@@ -98,10 +98,10 @@ class GServer
|
|
98
98
|
end
|
99
99
|
|
100
100
|
@@services = {} # Hash of opened ports, i.e. services
|
101
|
-
@@servicesMutex =
|
101
|
+
@@servicesMutex = DangoMutex.new(:gServer_servicesMutex)
|
102
102
|
|
103
103
|
def GServer.stop(port, host = DEFAULT_HOST)
|
104
|
-
@@servicesMutex.
|
104
|
+
@@servicesMutex.timeout_sync(10, :GServer_stop) {
|
105
105
|
@@services[host][port].stop
|
106
106
|
}
|
107
107
|
end
|
@@ -112,9 +112,9 @@ class GServer
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def stop
|
115
|
-
@connectionsMutex.
|
115
|
+
@connectionsMutex.timeout_sync(10, :stop) {
|
116
116
|
if @tcpServerThread
|
117
|
-
@tcpServerThread.raise "stop"
|
117
|
+
@tcpServerThread.raise "stop. "
|
118
118
|
end
|
119
119
|
}
|
120
120
|
end
|
@@ -182,7 +182,7 @@ class GServer
|
|
182
182
|
@host = host
|
183
183
|
@maxConnections = maxConnections
|
184
184
|
@connections = []
|
185
|
-
@connectionsMutex =
|
185
|
+
@connectionsMutex = DangoMutex.new(:gServer_connectionsMutex)
|
186
186
|
@connectionsCV = ConditionVariable.new
|
187
187
|
@stdlog = stdlog
|
188
188
|
@audit = audit
|
@@ -204,6 +204,7 @@ class GServer
|
|
204
204
|
@@services[@host][@port] = self;
|
205
205
|
}
|
206
206
|
@tcpServerThread = Thread.new {
|
207
|
+
Thread.current[:_name] = "thread gserver tcpServerThread"
|
207
208
|
begin
|
208
209
|
starting if @audit
|
209
210
|
while !@shutdown
|
@@ -249,7 +250,7 @@ class GServer
|
|
249
250
|
@connections.each { |c| c.raise "stop" }
|
250
251
|
end
|
251
252
|
@tcpServerThread = nil
|
252
|
-
@@servicesMutex.
|
253
|
+
@@servicesMutex.timeout_sync(10, :stopping) {
|
253
254
|
@@services[@host].delete(@port)
|
254
255
|
}
|
255
256
|
stopping if @audit
|
@@ -0,0 +1,115 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
=begin
|
4
|
+
= dango用のlogger
|
5
|
+
=end
|
6
|
+
|
7
|
+
|
8
|
+
require 'logger'
|
9
|
+
require 'thread'
|
10
|
+
require 'pp'
|
11
|
+
|
12
|
+
|
13
|
+
# クライアントとサーバーで共有するモジュール
|
14
|
+
module DangoLoggerModule
|
15
|
+
# ロガーの定義
|
16
|
+
def logger
|
17
|
+
# if !@dango_logger # これだと警告が出てうざいので
|
18
|
+
if !self.instance_variables.find{|iv| iv == '@dango_logger'} # @dango_loggerが未定義なら
|
19
|
+
# loggerの初回呼び出し時
|
20
|
+
@dango_logger = DangoLogger.new(@log_file, @log_shift_age, @log_max_size, @log_level)
|
21
|
+
end
|
22
|
+
|
23
|
+
@dango_logger
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Dango用のロガークラス
|
28
|
+
class DangoLogger
|
29
|
+
include ErrorMessage
|
30
|
+
|
31
|
+
def initialize(log_file, log_shift_age, log_max_size, log_level)
|
32
|
+
@log_file = log_file
|
33
|
+
@log_shift_age = log_shift_age
|
34
|
+
@log_max_size = log_max_size
|
35
|
+
@log_level = log_level
|
36
|
+
|
37
|
+
if @log_file && @log_file != "" # 出力ファイルが空なら何もしない
|
38
|
+
@is_logging = true
|
39
|
+
else
|
40
|
+
@is_logging = false
|
41
|
+
end
|
42
|
+
|
43
|
+
if @is_logging
|
44
|
+
log_dir = File.dirname(@log_file)
|
45
|
+
Dir.mkdir(log_dir) if !File.exist?(log_dir)
|
46
|
+
@dango_logger = Logger.new(@log_file, @log_shift_age, @log_max_size)
|
47
|
+
@dango_logger.level = @log_level
|
48
|
+
def @dango_logger.format_message(severity, timestamp, msg, progname)
|
49
|
+
now = Time.now
|
50
|
+
now_str = now.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % now.usec
|
51
|
+
"%1.1s, [%s] %s:%s\n" % [severity, now_str, msg,
|
52
|
+
progname]
|
53
|
+
end
|
54
|
+
@dango_logger.add(1, "--- start log ---", "logger")
|
55
|
+
|
56
|
+
@log_queue = Queue.new
|
57
|
+
|
58
|
+
Thread.start do
|
59
|
+
# logger作成
|
60
|
+
loop do
|
61
|
+
begin
|
62
|
+
data = @log_queue.pop
|
63
|
+
@dango_logger.add(data[:sev], data[:msg], data[:prg])
|
64
|
+
rescue Exception
|
65
|
+
puts "dango_logger:#{error_message($!, 'u')}"
|
66
|
+
exit! # ログのトラブルが出た場合は強制終了
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end # Thread.end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def debug(msg = "")
|
74
|
+
if @is_logging
|
75
|
+
@log_queue.push({:sev=>0, :msg=>msg, :prg=>Thread.current.object_id})
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def info(msg = "")
|
80
|
+
if @is_logging
|
81
|
+
@log_queue.push({:sev=>1, :msg=>msg, :prg=>Thread.current.object_id})
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def warn(msg = "")
|
86
|
+
if @is_logging
|
87
|
+
@log_queue.push({:sev=>2, :msg=>msg, :prg=>Thread.current.object_id})
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def error(msg = "")
|
92
|
+
if @is_logging
|
93
|
+
@log_queue.push({:sev=>3, :msg=>msg, :prg=>Thread.current.object_id})
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def fatal(msg = "")
|
98
|
+
if @is_logging
|
99
|
+
@log_queue.push({:sev=>4, :msg=>msg, :prg=>Thread.current.object_id})
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def unknown(msg = "")
|
104
|
+
if @is_logging
|
105
|
+
@log_queue.push({:sev=>5, :msg=>msg, :prg=>Thread.current.object_id})
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def add(sev, msg = "")
|
110
|
+
if @is_logging
|
111
|
+
@log_queue.push({:sev=>sev, :msg=>str, :prg=>Thread.current.object_id})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
=begin
|
4
|
+
= Dango用のMutex
|
5
|
+
=end
|
6
|
+
|
7
|
+
|
8
|
+
require 'thread'
|
9
|
+
|
10
|
+
# Mutexクラスの名前情報機能追加
|
11
|
+
class DangoMutex < Mutex
|
12
|
+
def initialize(mutex_name = nil)
|
13
|
+
@mutex_name = mutex_name.to_s
|
14
|
+
@lock_name = ""
|
15
|
+
super()
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader(:mutex_name, :lock_name)
|
19
|
+
|
20
|
+
# タイムアウトする排他処理
|
21
|
+
def timeout_sync(sec = 10, lock_name = "")
|
22
|
+
ret = nil
|
23
|
+
begin
|
24
|
+
timeout(sec, DangoFrameworkMutexTimeoutException) do
|
25
|
+
self.synchronize do
|
26
|
+
@lock_name = lock_name
|
27
|
+
ret = yield
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
rescue DangoFrameworkMutexTimeoutException, Timeout::Error, TimeoutError
|
32
|
+
|
33
|
+
# なぜかDangoFrameworkMutexTimeoutException以外の例外クラスが飛ぶことがあるので
|
34
|
+
if $!.class == DangoFrameworkMutexTimeoutException
|
35
|
+
error_msg = ""
|
36
|
+
else
|
37
|
+
error_msg = "#{$!.class}:"
|
38
|
+
end
|
39
|
+
|
40
|
+
locked_msg = ""
|
41
|
+
ObjectSpace.each_object(DangoMutex) do |object|
|
42
|
+
if object.locked?
|
43
|
+
locked_msg += "#{object.mutex_name.to_s}(#{object.lock_name.to_s}) "
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
error_msg += "DangoFrameworkMutexTimeoutException" +
|
48
|
+
"self=#{self.mutex_name}(#{lock_name})\n" +
|
49
|
+
"locked_mutex=#{locked_msg}\n" +
|
50
|
+
"#{$!.message}\n" +
|
51
|
+
"#{$!.backtrace.pretty_inspect}"
|
52
|
+
|
53
|
+
raise(DangoFrameworkMutexTimeoutException, error_msg)
|
54
|
+
|
55
|
+
rescue Exception
|
56
|
+
puts "#{$!.class} #{$!.message}\n#{$!.backtrace.pretty_inspect}"
|
57
|
+
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
|
61
|
+
ret
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
=begin
|
4
|
+
= デフォルトのdango_receive_*群
|
5
|
+
=end
|
6
|
+
|
7
|
+
# デフォルトのdango_receive_*群
|
8
|
+
module DefaultDangoReceive
|
9
|
+
# クライアントから来たheart_beatなら
|
10
|
+
def dango_receive__notice_heart_beat(ret_obj)
|
11
|
+
logger.debug "dango_receive__notice_heart_beat:#{session[:sid]}:#{ret_obj['_hb_id']} "
|
12
|
+
|
13
|
+
shared.transaction(:_heart_beat_time_hash) do |heart_beat_time_hash|
|
14
|
+
heart_beat_time_hash[session[:sid]] = Time.now
|
15
|
+
shared.commit(heart_beat_time_hash)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# action_nameがエンコード変更なら
|
20
|
+
def dango_receive__change_encode_type(ret_obj)
|
21
|
+
logger.debug "dango_receive__change_encode_type: #{ret_obj['encode_type'].inspect}"
|
22
|
+
session[:encode_type] = ret_obj['encode_type']
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
################## メンテナンスアクション系 ##################
|
28
|
+
|
29
|
+
public
|
30
|
+
# メンテナンスコマンド:サーバーからクライアントへのデータ送信
|
31
|
+
def dango_receive__monitor_get_server_info(ret_obj)
|
32
|
+
logger.debug "dango_receive__monitor_get_server_info:#{ret_obj.inspect}"
|
33
|
+
dango_check_monitor_error()
|
34
|
+
|
35
|
+
get_server_info = {
|
36
|
+
'server_start_time' => start_time.strftime("%Y-%m-%d %H:%M:%S"),
|
37
|
+
'up_time' => Time.now - start_time,
|
38
|
+
|
39
|
+
'recv_count' => recv_count, # 受信回数
|
40
|
+
'send_count' => send_count, # 送信回数
|
41
|
+
'recv_fail_count' => recv_fail_count, # 受信失敗回数
|
42
|
+
'send_fail_count' => send_fail_count, # 送信失敗回数
|
43
|
+
|
44
|
+
'log_level' => log_level_str,
|
45
|
+
'log_file' => log_file,
|
46
|
+
'log_max_size' => log_max_size,
|
47
|
+
'log_shift_age' => log_shift_age,
|
48
|
+
}
|
49
|
+
|
50
|
+
send_obj = {'code'=>0, 'get_server_info'=>get_server_info}
|
51
|
+
send_notice('return__monitor_get_server_info', session[:sid], send_obj, :type=>2)
|
52
|
+
end
|
53
|
+
|
54
|
+
# メンテナンスコマンド:サーバーからクライアントへのデータ送信
|
55
|
+
def dango_receive__monitor_get_shared(ret_obj)
|
56
|
+
logger.debug "dango_receive__monitor_get_shared:#{ret_obj.inspect}"
|
57
|
+
dango_check_monitor_error()
|
58
|
+
|
59
|
+
send_obj = {'code'=>0, 'get_shared'=>shared.to_hash}
|
60
|
+
send_notice('return__monitor_get_shared', session[:sid], send_obj, :type=>2)
|
61
|
+
end
|
62
|
+
|
63
|
+
# メンテナンスコマンド:サーバーからクライアントへのデータ送信
|
64
|
+
def dango_receive__monitor_get_session_list(ret_obj)
|
65
|
+
logger.debug "dango_receive__monitor_get_session_list:#{ret_obj.inspect}"
|
66
|
+
dango_check_monitor_error()
|
67
|
+
|
68
|
+
send_obj = {'code'=>0, 'get_session_list'=>session_list}
|
69
|
+
send_notice('return__monitor_get_session_list', session[:sid], send_obj, :type=>2)
|
70
|
+
end
|
71
|
+
|
72
|
+
# メンテナンスコマンド:サーバーからクライアントへのデータ送信
|
73
|
+
def dango_receive__monitor_get_socket_list(ret_obj)
|
74
|
+
logger.debug "dango_receive__monitor_get_socket_list:#{ret_obj.inspect}"
|
75
|
+
dango_check_monitor_error()
|
76
|
+
|
77
|
+
send_obj = {'code'=>0, 'get_socket_list'=>socket_list.keys}
|
78
|
+
send_notice('return__monitor_get_socket_list', session[:sid], send_obj, :type=>2)
|
79
|
+
end
|
80
|
+
|
81
|
+
# メンテナンスコマンド:サーバーデータ再読み込み
|
82
|
+
def dango_receive__monitor_server_reload(ret_obj)
|
83
|
+
logger.debug "dango_receive__monitor_server_reload"
|
84
|
+
dango_check_monitor_error()
|
85
|
+
|
86
|
+
@server_reload = true
|
87
|
+
logger.debug "@server_reload=#{@server_reload.inspect}"
|
88
|
+
send_obj = {'code'=>0, 'message'=>'success'}
|
89
|
+
send_notice('return__monitor_server_reload', session[:sid], send_obj, :type=>2)
|
90
|
+
end
|
91
|
+
|
92
|
+
# メンテナンスコマンド:接続者全員へメッセージ送信
|
93
|
+
def dango_receive__monitor_send_system_message(ret_obj)
|
94
|
+
logger.debug "dango_receive__monitor_send_system_message:#{ret_obj.inspect}"
|
95
|
+
dango_check_monitor_error()
|
96
|
+
|
97
|
+
# 全員へ_notice_system_messageを通知
|
98
|
+
socket_list.keys.each do |sid|
|
99
|
+
next if session[:sid] == sid
|
100
|
+
send_obj = { "message" => ret_obj["message"] }
|
101
|
+
send_notice('_notice_system_message', sid, send_obj)
|
102
|
+
end
|
103
|
+
|
104
|
+
send_obj = {'code'=>0, }
|
105
|
+
send_notice('return__monitor_send_system_message', session[:sid], send_obj, :type=>2)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
# メンテナンスコマンド:エラーの場合
|
110
|
+
def dango_check_monitor_error()
|
111
|
+
action_name = session[:_action_name]
|
112
|
+
peerhost = session[:peer_host]
|
113
|
+
peeraddr = session[:peer_ip_address]
|
114
|
+
|
115
|
+
logger.debug "dango_check_monitor_error:peerhost=#{peerhost.inspect} peeraddr=#{peeraddr.inspect} @backdoor_host=#{@backdoor_host.inspect}"
|
116
|
+
|
117
|
+
match = false
|
118
|
+
if peerhost == backdoor_host # ホスト名で書いてある時の一致確認
|
119
|
+
match = true
|
120
|
+
else
|
121
|
+
begin # IPアドレスの一致確認
|
122
|
+
# match = true if IPAddr.new(@backdoor_host).include?(peeraddr)
|
123
|
+
if IPAddr.new(@backdoor_host).include?(IPAddr.new(peeraddr))
|
124
|
+
match = true
|
125
|
+
end
|
126
|
+
rescue
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if !match
|
131
|
+
notice_name = "return_" + action_name
|
132
|
+
send_obj = {'code'=>1, 'message'=>"error your ip address"}
|
133
|
+
send_notice(notice_name, session[:sid], send_obj, :type=>2)
|
134
|
+
raise(DangoFrameworkMonitorSecurityError)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
end
|
140
|
+
|