Class: TestClient

Inherits:
DangoClientFramework show all
Defined in:
lib/dango/tester/dango_tester_client.rb

Overview

テスト接続用のクラス

Constant Summary collapse

SendReceiveSleepIntervalSec =

データ送信後の順の際のタイムアウトチェック間隔秒

0.03
ReceiveWaitTimeoutSec =

データ受信確認の待ち秒数

10
ReceiveTrapTimeoutSec =

データ受信確認のトラップの秒数

0

Constants inherited from DangoClientFramework

DangoClientFramework::HeartBeatSendIntervalSec

Constants included from DangoFrameworkModule

DangoFrameworkModule::CommMaxDigit, DangoFrameworkModule::DefaultDataType, DangoFrameworkModule::MaxLen

Instance Attribute Summary collapse

Attributes inherited from DangoClientFramework

#sid

Attributes included from DangoFrameworkModule

#dango_logger

Instance Method Summary collapse

Methods inherited from DangoClientFramework

#dango_client_close, #dango_client_notice_shared, #dango_client_notice_shared_init, #dango_client_receive_decrypt, #dango_client_send_encrypt, #dango_heart_beat_thread_init, #dango_receive__heart_beat, #dango_receive__notice_sid, #dango_receive__notice_system_message, #dango_receive_decrypt, #dango_send_encrypt, #dango_session_closed, #method_missing, #send_action, #send_action_return_notice, #send_return_shared, #send_return_shared_init

Methods included from DangoFrameworkModule

#dango_receive_data, #dango_send_data, #debug_print, #logger

Methods included from ErrorMessage

#error_message

Constructor Details

#initialize(env, config, c_name) ⇒ TestClient

Returns a new instance of TestClient.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/dango/tester/dango_tester_client.rb', line 104

def initialize(env, config, c_name)
  @config = config
  @client_name = c_name # クライアント名

  
  super(env, config)
  
  @receive_mutex = Mutex.new # 送受信用の排他処理

  @receive_arr = []
  @trap_thread_hash = {}
  
  @receive_methods = []
  
  send_receive_shared_init()
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class DangoClientFramework

Instance Attribute Details

#client_nameObject

Returns the value of attribute client_name.



119
120
121
# File 'lib/dango/tester/dango_tester_client.rb', line 119

def client_name
  @client_name
end

#send_receive_sharedObject (readonly)

Returns the value of attribute send_receive_shared.



125
126
127
# File 'lib/dango/tester/dango_tester_client.rb', line 125

def send_receive_shared
  @send_receive_shared
end

Instance Method Details

#cancel_trap_receive(notice_name, options = {}) ⇒ Object

cancel trap_receive



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/dango/tester/dango_tester_client.rb', line 237

def cancel_trap_receive(notice_name, options = {})
  logger.debug "cancel_trap_receive:#{notice_name}:"
  
  # trapスレッドの削除

  if @trap_thread_hash[notice_name] 
    logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
    @trap_thread_hash[notice_name].kill
    logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
    @trap_thread_hash[notice_name].join
    logger.debug "cancel_trap_receive:#{@trap_thread_hash[notice_name].status }:"
    
    @trap_thread_hash.delete(notice_name)
  end
  
  # 受信データのごみを削除

  send_receive_shared[notice_name] = nil 
  
  @receive_mutex.synchronize do
    @receive_arr.delete_if{|r| r[0] == notice_name}
  end
end

#dango_client_initObject

起動処理



128
129
130
131
132
133
134
135
136
# File 'lib/dango/tester/dango_tester_client.rb', line 128

def dango_client_init
  # サーバー接続情報など

  @connection_client_host = @config["network"]["host"] # 自動でこのホスト名でサーバー開始

  @connection_client_port = @config["network"]["port"] # 自動でこのポートでサーバー開始

  
  # ログ出力情報

  @connection_client_log_file = "log/tester_#{@client_name}.log" # 自動でこのログファイル名を使う

  @connection_client_log_level = Logger::DEBUG # 自動でこのログレベルになる

end

#receive_arrObject

receive_arrの状態確認



296
297
298
299
300
301
302
# File 'lib/dango/tester/dango_tester_client.rb', line 296

def receive_arr
  receive_arr = nil
  @receive_mutex.synchronize do
    receive_arr = @receive_arr.deep_dup
  end
  receive_arr
end

#send(name, send_obj = {}) ⇒ Object

テストサーバー



139
140
141
142
# File 'lib/dango/tester/dango_tester_client.rb', line 139

def send(name, send_obj = {})
  logger.debug("tester.send:send_obj=#{send_obj.inspect} ")
  send_action(name, send_obj)
end

#send_receive_shared_initObject

dango_client_send_receive_data用の共有メモリ



122
123
124
# File 'lib/dango/tester/dango_tester_client.rb', line 122

def send_receive_shared_init
  @send_receive_shared = SharedMemoryStore.new
end

#trap_receive(notice_name, options = {}) ⇒ Object

trap_receive

Raises:

  • (ArgumentError)


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/dango/tester/dango_tester_client.rb', line 145

def trap_receive(notice_name, options = {})
  logger.debug "trap_receive_data:#{notice_name}:"
  timeout = options[:timeout] || ReceiveTrapTimeoutSec
  trap_proc = options[:proc] || nil
  trap_loop = options[:loop] || nil # procがある場合のみ有効なフラグ

  raise(ArgumentError, ":proc is not Proc class.") if trap_proc && ! trap_proc.is_a?(Proc)
  
  # 戻ってきたデータのチェックメソッド

  
#    if ! @receive_methods.include?(notice_name_sym)

    notice_name_sym = (notice_name.class == Symbol) ? (":"+notice_name.to_s) : ('"'+notice_name+'"')
    instance_method_name = "dango_receive_#{notice_name}"
    expr = "      def self.\#{instance_method_name}(ret_obj)\n        logger.debug \"ret_obj:\#{notice_name_sym}:\" + ret_obj.inspect + \" \" + Time.now_to_s\n        send_receive_shared[\#{notice_name_sym}] = ret_obj\n      end\n    EOF\n    instance_eval expr\n#      @receive_methods.push(notice_name_sym)\n#    end\n  \n  # @trap_thread_hash\u306B\u30B9\u30EC\u30C3\u30C9\u767B\u9332\n  if ! @trap_thread_hash.has_key?(notice_name)\n    \n    # \u30B9\u30EC\u30C3\u30C9\u958B\u59CB\n    th = Thread.start(notice_name, timeout, trap_proc, trap_loop) do\n      loop do\n        send_receive_shared[notice_name] = nil\n        if timeout == 0\n          end_reserved_time = Time.at(0)         # 0\u306A\u3089epoch\u3092\u5165\u308C\u308B\n        else\n          end_reserved_time = Time.now + timeout # 0\u4EE5\u4E0A\u306A\u3089\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u6642\u9593\u6C7A\u5B9A\n        end\n        \n        # \u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u30C1\u30A7\u30C3\u30AF\n        loop do\n          if end_reserved_time != Time.at(0) && end_reserved_time < Time.now\n            raise(DangoFrameworkTimeoutError, \"timeout:timeout_sec=\#{timeout}: \\n client_name=\#{@client_name}(\#{self.sid}): \\n notice_name=\#{notice_name}\") \n          end\n          \n          # \u623B\u3063\u3066\u304D\u305F\u30C7\u30FC\u30BF\u304C\u3042\u308C\u3070\n          if send_receive_shared[notice_name]\n            logger.debug \"notice_name:\#{notice_name}:\#{send_receive_shared[notice_name].inspect} \"\n            break \n          end\n          \n          sleep SendReceiveSleepIntervalSec # \u30B9\u30EA\u30FC\u30D7\n        end\n        \n        # \u623B\u3063\u3066\u304D\u305F\u30C7\u30FC\u30BF\u304C\u3042\u308B\u304B\u3069\u3046\u304B\u30C1\u30A7\u30C3\u30AF\n        if !send_receive_shared[notice_name] \n          raise(DangoFrameworkError, \"received data is none. sid=\#{self.sid} notice_name=\#{notice_name}\")\n        end\n        \n        # :proc\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u305D\u308C\u3092\u547C\u3073\u51FA\u3059\n        if trap_proc\n          logger.debug \"trap_receive_data:trap_proc:\#{trap_proc.inspect} \"\n          trap_proc.call(send_receive_shared[notice_name])\n          send_receive_shared[notice_name] = nil\n          break if ! trap_loop # loop\u3059\u308B\u5FC5\u8981\u304C\u306A\u3051\u308C\u3070\u30B9\u30EC\u30C3\u30C9\u7D42\u4E86\n          \n        # :proc\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u306A\u3051\u308C\u3070\u3001wait\u7528\u306B@receive_arr\u306B\u5165\u308C\u3066\u304A\u304F\n        else\n          @receive_mutex.synchronize do\n            logger.debug \"notice_name:\#{notice_name}:\#{send_receive_shared[notice_name].inspect} \"\n            @receive_arr.push([notice_name.deep_dup, send_receive_shared[notice_name].deep_dup])\n            send_receive_shared[notice_name] = nil\n          end\n          break # \u30B9\u30EC\u30C3\u30C9\u7D42\u4E86\n          \n        end\n      end # loop\n      \n      # \u30E1\u30BD\u30C3\u30C9\u306E\u524A\u9664\n      instance_method_name = \"dango_receive_\#{notice_name}\"\n      expr = <<-EOF\n        def self.\#{instance_method_name}(ret_obj); end\n      EOF\n      instance_eval expr\n      \n    end # Thread\n    \n    @trap_thread_hash[notice_name] = th\n  else\n    \n    logger.debug \"trap_receive_data:already register trap:notice_name:\#{notice_name} \"\n  end\n  \nend\n"

#wait_receive(notice_name, options = {}) ⇒ Object

wait_receive



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/dango/tester/dango_tester_client.rb', line 260

def wait_receive(notice_name, options = {})
  logger.debug "wait_receive_data:#{notice_name}:"
  timeout = options[:timeout] || ReceiveWaitTimeoutSec
  
  # データ受信待ち

  receive_data = nil
  
  end_reserved_time = Time.now + timeout # 0以上ならタイムアウト時間決定

  
  loop do
    @receive_mutex.synchronize do
      receive_data = @receive_arr.find{|r| r[0] == notice_name}.deep_dup
    end
    
    break if receive_data != nil
    break if end_reserved_time < Time.now
    
    sleep SendReceiveSleepIntervalSec # スリープ

  end
  
  # タイムアウトなら

  if receive_data == nil
    raise(DangoFrameworkTimeoutError, "timeout:timeout_sec=#{timeout}: \n client_name=#{@client_name}(#{self.sid}) \n :notice_name=#{notice_name} \n") 
  end
  
  # 結果を削除しておく

  @receive_mutex.synchronize do
    @receive_arr.delete_if{|r| r[0] == notice_name}
  end
  
  @trap_thread_hash.delete(notice_name)
  
  receive_data[1]
end