dango 0.4.8 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ #!ruby -Ku
2
+
3
+ =begin
4
+ = エラーメッセージ出力用
5
+ =end
6
+
7
+
8
+ require 'pp'
9
+
10
+
11
+ # エラー出力用モジュール
12
+ module ErrorMessage
13
+ # デバッグ出力用のメソッド
14
+ def error_message(exception_class, code = nil)
15
+ if exception_class.kind_of?(Exception)
16
+ "#{exception_class.class} is not Exception class"
17
+ end
18
+
19
+ str = "class=#{exception_class.class}\n" +
20
+ "message=#{exception_class.message}\n" +
21
+ "backtrace=#{exception_class.backtrace.pretty_inspect}"
22
+ if code.to_s.downcase == "u" || code.to_s.downcase == "utf8"
23
+ str = str.toutf8
24
+ elsif code.to_s.downcase == "s" || code.to_s.downcase == "sjis"
25
+ str = str.tosjis
26
+ end
27
+ str
28
+ end
29
+ end
30
+
@@ -7,7 +7,6 @@
7
7
 
8
8
  require 'socket'
9
9
  require 'logger'
10
- require 'thread'
11
10
  require 'timeout'
12
11
  require 'yaml'
13
12
  require "stringio"
@@ -18,8 +17,26 @@ require "fcntl"
18
17
  require "rubygems"
19
18
  require 'json/add/rails'
20
19
 
20
+ require 'thread'
21
+ #require 'fastthread'
21
22
 
22
- require "dango/shared/memory_store.rb"
23
+ require "dango/error_message"
24
+ require "dango/dango_logger"
25
+ require "dango/dango_mutex"
26
+ require "dango/shared/memory_store"
27
+
28
+
29
+ # 例外定義
30
+ class DangoFrameworkException < StandardError; end
31
+ class DangoFrameworkTimeoutException < DangoFrameworkException; end
32
+ class DangoFrameworkConnectionException < DangoFrameworkException; end
33
+ class DangoFrameworkDisconnectException < DangoFrameworkException; end
34
+ class DangoFrameworkReadNoDataException < DangoFrameworkException; end
35
+ class DangoFrameworkReadTimeoutException < DangoFrameworkException; end
36
+ class DangoFrameworkFlashPolicyException < DangoFrameworkException; end
37
+ class DangoFrameworkMonitorSecurityException < DangoFrameworkException; end
38
+ class DangoFrameworkTransactionException < DangoFrameworkException; end
39
+ class DangoFrameworkMutexTimeoutException < DangoFrameworkException; end
23
40
 
24
41
 
25
42
  class Object
@@ -31,7 +48,6 @@ class Object
31
48
  sio.rewind
32
49
  sio.read
33
50
  end
34
-
35
51
  str
36
52
  end
37
53
  end
@@ -44,45 +60,18 @@ end
44
60
  # Timeクラスの表示形式修正
45
61
  class Time
46
62
  def self.now_to_s
47
- # self.strftime("%Y-%m-%d %H:%M:%S")
48
63
  now = self.now
49
64
  now.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % now.usec
50
65
  end
51
- end
52
-
53
- # 例外定義
54
- class DangoFrameworkException < StandardError; end
55
- class DangoFrameworkTimeoutException < DangoFrameworkException; end
56
- class DangoFrameworkConnectionException < DangoFrameworkException; end
57
- class DangoFrameworkDisconnectException < DangoFrameworkException; end
58
- class DangoFrameworkReadNoDataException < DangoFrameworkException; end
59
- class DangoFrameworkReadTimeoutException < DangoFrameworkException; end
60
- class DangoFrameworkFlashPolicyException < DangoFrameworkException; end
61
- class DangoFrameworkMonitorSecurityException < DangoFrameworkException; end
62
- class DangoFrameworkTransactionException < DangoFrameworkException; end
63
-
64
-
65
- # エラー出力用モジュール
66
- module ErrorMessage
67
- # デバッグ出力用のメソッド
68
- def error_message(exception_class, code = nil)
69
- if exception_class.kind_of?(Exception)
70
- "#{exception_class.class} is not Exception class"
71
- end
72
-
73
- str = "#{exception_class.class}:#{exception_class.message}\n" +
74
- "#{exception_class.backtrace.pretty_inspect}"
75
- if code.to_s.downcase == "u" || code.to_s.downcase == "utf8"
76
- str = str.toutf8
77
- elsif code.to_s.downcase == "s" || code.to_s.downcase == "sjis"
78
- str = str.tosjis
79
- end
80
- str
66
+ def to_ss
67
+ self.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % self.usec
81
68
  end
82
69
  end
83
70
 
84
71
  # ユーティティ
85
72
  module DangoUtilModule
73
+ include ErrorMessage
74
+
86
75
  # 配列をランダムに並べ替え
87
76
  # arrは順番を入れ替えたい配列
88
77
  # numは入れ替え回数(省略時2、大きな数を入れると確実にランダムになるが時間が掛かる)
@@ -97,11 +86,71 @@ module DangoUtilModule
97
86
  # end
98
87
  # ret_arr
99
88
  end
89
+
90
+ def get_process_info(pid_orig = nil) # プロセス情報取得
91
+ if pid_orig
92
+ pid = pid_orig.deep_dup
93
+ else
94
+ pid = Process.pid
95
+ end
96
+
97
+ ret = ""
98
+ ret += "=== get_process_info ===\n"
99
+ ret += "DangoUtilModule::pid = #{pid}\n"
100
+ ret += "DangoUtilModule::RUBY_VERSION = #{RUBY_VERSION}\n"
101
+ ret += "DangoUtilModule::RUBY_RELEASE_DATE = #{RUBY_RELEASE_DATE}\n"
102
+ ret += "DangoUtilModule::RUBY_PLATFORM = #{RUBY_PLATFORM}\n"
103
+
104
+ if RUBY_PLATFORM == 'i386-mswin32'
105
+
106
+ else
107
+ proc_process_dir = "/proc/#{pid}"
108
+ begin
109
+ if File.directory?(proc_process_dir)
110
+ # 開始時間
111
+ ret += "DangoUtilModule::process start time=#{File.mtime(proc_process_dir).to_ss}\n"
112
+
113
+ # /proc/#{pid}/statusを読み込む
114
+ proc_process_status = "/proc/#{pid}/status"
115
+
116
+ if File.file?(proc_process_status) && File.readable?(proc_process_status)
117
+ if RUBY_PLATFORM != 'i386-cygwin' # cygwinだとなぜか落ちるので分離
118
+ open(proc_process_status, "rb") do |fh|
119
+ ret += "DangoUtilModule::get_process_info:proc_process_status\n#{fh.read}\n"
120
+ end
121
+ end
122
+ end
123
+
124
+ # /proc/#{pid}/fdの中の一覧を取得
125
+ proc_process_fd = "/proc/#{pid}/fd"
126
+ if File.directory?(proc_process_fd) && File.executable?(proc_process_fd)
127
+ ret += "DangoUtilModule::get_process_info:proc_process_fd:#{proc_process_fd}\n"
128
+ Dir.foreach(proc_process_fd) do |file|
129
+ file_fullpath = "#{proc_process_fd}/#{file}"
130
+ if File.symlink?(file_fullpath)
131
+ ret += " #{file_fullpath} -> #{File.readlink(file_fullpath)}\n"
132
+ else
133
+ ret += " #{file_fullpath}\n"
134
+ end
135
+ end
136
+ end
137
+ else
138
+ ret += "DangoUtilModule::#{proc_process_dir} is not exist"
139
+ end
140
+ rescue
141
+ ret += "DangoUtilModule:: #{error_message($!, 'u')}"
142
+ end
143
+ end
144
+
145
+ ret
146
+ end
147
+
100
148
  end
101
149
 
102
150
  # クライアントとサーバーで共有するモジュール
103
151
  module DangoFrameworkModule
104
152
  include ErrorMessage
153
+ include DangoLoggerModule
105
154
 
106
155
  CommMaxDigit = 5 # 通信の最大桁数
107
156
  MaxLenRecv = 1024 # 通信の一度の送信バイト数
@@ -131,45 +180,14 @@ module DangoFrameworkModule
131
180
  puts str
132
181
  end
133
182
 
134
- # ロガーの定義
135
- def logger
136
- # if !@dango_logger # これだと警告が出てうざいので
137
- if !self.instance_variables.find{|iv| iv == '@dango_logger'} # @dango_loggerが未定義なら
138
-
139
- if @log_file == "" # ログを取らない設定の場合は
140
- @dango_logger = "LOG NONE"
141
- def @dango_logger.fatal(str); end
142
- def @dango_logger.error(str); end
143
- def @dango_logger.info(str) ; end
144
- def @dango_logger.warn(str) ; end
145
- def @dango_logger.debug(str); end
146
-
147
- else # ログを取る設定の場合は
148
- log_dir = File.dirname(@log_file)
149
- Dir.mkdir(log_dir) if !File.exist?(log_dir)
150
- @dango_logger = Logger.new(@log_file, @log_shift_age, @log_max_size)
151
- @dango_logger.level = @log_level
152
- def @dango_logger.format_message(severity, timestamp, msg, progname)
153
- now = Time.now
154
- now_str = now.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % now.usec
155
- "%1.1s, [%s] %d:%s %s\n" % [severity, now_str, Thread.current.object_id, progname, msg]
156
- end
157
- end
158
-
159
- end
160
-
161
- @dango_logger
162
- end
163
-
164
- attr(:dango_logger)
165
-
166
183
  # データ受信処理
167
184
  def dango_receive_data(sock)
168
- logger.debug "dango_receive_data:start:sock=#{sock}"
169
185
  ret_data = ""
170
186
 
171
187
  begin
172
188
  size_str = sock.recv(CommMaxDigit + 1)
189
+ logger.debug "dango_receive_data:read header:sock=#{sock}"
190
+
173
191
  rescue EOFError, IOError, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNABORTED
174
192
  # 接続終了時の切断と思われるものはDangoFrameworkConnectionExceptionにしない
175
193
  raise(DangoFrameworkDisconnectException, "failed to read sock for EOF reached (and so on). " +
@@ -205,7 +223,10 @@ module DangoFrameworkModule
205
223
  raise(DangoFrameworkConnectionException, "too big... size=#{size}:size_str=#{size_str.inspect}")
206
224
  end
207
225
 
208
- ret_data_orig = ""
226
+ logger.warn "warn size is too big ? size=#{size}:size_str=#{size_str.inspect}" if size > 10000
227
+
228
+
229
+ recv_data_orig = ""
209
230
 
210
231
  # 10秒でタイムアウトを起こす
211
232
  timeout(ReadTimeoutSec, DangoFrameworkReadTimeoutException) do
@@ -214,34 +235,41 @@ module DangoFrameworkModule
214
235
  while size > 0
215
236
  read_len = MaxLenRecv > size ? size : MaxLenRecv
216
237
  begin
217
- this_ret_data_orig = sock.recv(read_len)
238
+ this_recv_data_orig = sock.recv(read_len)
218
239
  rescue
219
240
  raise(DangoFrameworkConnectionException, "failed to read sock(data).\n#{error_message($!, 'u')}")
220
241
  end
221
242
 
222
- ret_data_orig += this_ret_data_orig
243
+ recv_data_orig += this_recv_data_orig
223
244
 
224
- size -= this_ret_data_orig.size
245
+ size -= this_recv_data_orig.size
225
246
  end
226
247
  end
227
248
 
228
- ret_data = dango_receive_decrypt(ret_data_orig[0..-2])
249
+ recv_data = receive_decrypt(recv_data_orig[0..-2])
229
250
 
230
251
  @recv_count += 1 if @recv_count # 受信回数カウント
231
252
 
232
253
  begin
233
- if ret_data == "" || ret_data == "{}" # データが空ならparseしない
234
- data = []
254
+ if recv_data == "" || recv_data == "{}" # データが空ならparseしない
255
+ ret_data = []
235
256
  elsif encode_type == EncodeTypeJSON
236
- data = JSON.parse(ret_data)
257
+ ret_data = JSON.parse(recv_data)
237
258
  elsif encode_type == EncodeTypeYAML
238
- data = YAML::load(ret_data)
259
+ ret_data = YAML::load(recv_data)
239
260
  elsif encode_type == EncodeTypeMarshal
240
- data = Marshal.load(ret_data)
261
+ ret_data = Marshal.load(recv_data)
262
+ end
263
+
264
+ if ret_data.class != Array
265
+ raise(DangoFrameworkConnectionException, "data is not array.#{$!.class}\nret_data=#{ret_data}")
241
266
  end
267
+
242
268
  rescue
243
269
  raise(DangoFrameworkConnectionException, "data parse error.#{$!.class}\nret_data=#{ret_data}")
244
270
  end
271
+
272
+ ret_data
245
273
  end
246
274
 
247
275
  # データ送信処理
@@ -251,7 +279,12 @@ module DangoFrameworkModule
251
279
  if send_objs == []
252
280
  send_data_orig = ""
253
281
  elsif encode_type == EncodeTypeJSON
254
- send_data_orig = JSON.generate(send_objs)
282
+ begin
283
+ send_data_orig = JSON.generate(send_objs)
284
+ rescue
285
+ pp send_objs
286
+ raise
287
+ end
255
288
  elsif encode_type == EncodeTypeYAML
256
289
  send_data_orig = send_objs.to_yaml
257
290
  elsif encode_type == EncodeTypeMarshal
@@ -260,7 +293,7 @@ module DangoFrameworkModule
260
293
  send_data_orig = JSON.generate(send_objs)
261
294
  end
262
295
 
263
- send_data = dango_send_encrypt(send_data_orig) + "\n"
296
+ send_data = send_encrypt(send_data_orig) + "\n"
264
297
 
265
298
  size = send_data.size
266
299
 
@@ -0,0 +1,131 @@
1
+ #!ruby -Ku
2
+
3
+ =begin
4
+ = Dangoサーバーのメインモジュール(drbで呼び出す用)
5
+ =end
6
+
7
+ # メインモジュール(drbで呼び出す用)
8
+ module ServerMonitorModule
9
+ # drbから呼ばれるメンテナンス:サーバーからクライアントへのデータ送信
10
+ def _monitor_get_server_info(ret_obj)
11
+ logger.debug "_monitor_get_server_info"
12
+
13
+ get_server_info = {
14
+ 'server_start_time' => start_time.strftime("%Y-%m-%d %H:%M:%S"),
15
+ 'up_time' => Time.now - start_time,
16
+
17
+ 'recv_count' => recv_count, # 受信回数
18
+ 'send_count' => send_count, # 送信回数
19
+ 'recv_fail_count' => recv_fail_count, # 受信失敗回数
20
+ 'send_fail_count' => send_fail_count, # 送信失敗回数
21
+
22
+ # 'log_level' => log_level_str,
23
+ # 'log_file' => log_file,
24
+ # 'log_max_size' => log_max_size,
25
+ # 'log_shift_age' => log_shift_age,
26
+ }
27
+
28
+ get_server_info
29
+ end
30
+
31
+ # drbから呼ばれるメンテナンス:サーバーデータ再読み込み
32
+ def _monitor_server_reload(ret_obj)
33
+ logger.debug "_monitor_server_reload"
34
+ @server_reload = true
35
+ true
36
+ end
37
+
38
+ # drbから呼ばれるメンテナンス:接続者全員へメッセージ送信
39
+ def _monitor_send_system_message(ret_obj)
40
+ logger.debug "_monitor_send_system_message"
41
+
42
+ # 全員へ_notice_system_messageを通知
43
+ socket_list.all_sid.each do |sid|
44
+ next if session[:sid] == sid
45
+ send_obj = { "message" => ret_obj["message"] }
46
+ send_notice('_notice_system_message', sid, send_obj)
47
+ end
48
+
49
+ true
50
+ end
51
+
52
+ # drbから呼ばれるメンテナンス:スレッド一覧
53
+ def _monitor_thread_status(ret_obj)
54
+ logger.debug "_monitor_thread_status"
55
+ ret = []
56
+
57
+ Thread.list.each do |th|
58
+ ret.push({
59
+ :object_id => th.object_id,
60
+ :name => th[:_name] ? th[:_name] : "unknown(maybe drb thread)",
61
+ })
62
+ end
63
+
64
+ ret
65
+ end
66
+
67
+ # drbから呼ばれるメンテナンス:排他処理一覧
68
+ def _monitor_mutex_status(ret_obj)
69
+ logger.debug "_monitor_mutex_status"
70
+ ret = []
71
+
72
+ ObjectSpace.each_object(DangoMutex) do |object|
73
+ ret.push({
74
+ :name => object.mutex_name,
75
+ :is_lock => object.locked?,
76
+ })
77
+ end
78
+
79
+ # mutex_list = [
80
+ # [:mutex_send_response, @mutex_send_response],
81
+ # [:mutex_send_notice , @mutex_send_notice],
82
+ # [:mutex_proc_thread , @mutex_proc_thread],
83
+ # [:mutex_send_response, @mutex_send_response],
84
+ # ]
85
+ # @mutex_sock.each do |key, value|
86
+ # mutex_list.push(["mutex_sock #{key}", value])
87
+ # end
88
+ #
89
+ # mutex_list.each do |name, mutex|
90
+ # ret.push({
91
+ # :name => name.to_s,
92
+ # :is_lock => mutex.locked?,
93
+ # })
94
+ # end
95
+
96
+ ret
97
+ end
98
+
99
+ # drbから呼ばれるメンテナンス:shareの取得
100
+ # key value
101
+ def _monitor_get_shared(ret_obj)
102
+ logger.debug "_monitor_get_shared:ret_obj=#{ret_obj.inspect}"
103
+ shared.to_hash
104
+ end
105
+
106
+ # drbから呼ばれるメンテナンス:shareの強制書き換え
107
+ # key value
108
+ def _monitor_write_shared(ret_obj)
109
+ logger.debug "_monitor_write_shared:ret_obj=#{ret_obj.inspect}"
110
+ logger.debug "_monitor_write_shared:value=#{eval(ret_obj['value']).inspect}"
111
+
112
+ shared[ret_obj["key"]] = eval(ret_obj['value'])
113
+ true
114
+ end
115
+
116
+ # drbから呼ばれるメンテナンス:session_listの取得
117
+ def _monitor_get_session_list(ret_obj)
118
+ logger.debug "_monitor_get_session_list:#{ret_obj.inspect}"
119
+ session_list
120
+ end
121
+
122
+ # drbから呼ばれるメンテナンス:socket_listの取得
123
+ def _monitor_get_socket_list(ret_obj)
124
+ logger.debug "_monitor_get_socket_list:#{ret_obj.inspect}"
125
+ ret = {}
126
+ socket_list.all_sid.each{|sid| ret[sid] = socket_list[sid].object_id}
127
+ ret
128
+ end
129
+
130
+ end
131
+