Class: DangoRakeUtil

Inherits:
Object show all
Includes:
DangoUtilModule
Defined in:
lib/dango/tasks/dango_rake.rb

Constant Summary collapse

CheckConnectLogFile =

テスト接続のログ

"log/check_dango_connect.log"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DangoUtilModule

#array_random, #get_process_info

Methods included from ErrorMessage

#error_message

Constructor Details

#initializeDangoRakeUtil

Returns a new instance of DangoRakeUtil.



17
18
19
# File 'lib/dango/tasks/dango_rake.rb', line 17

def initialize
  @log = ""
end

Instance Attribute Details

#logObject

Returns the value of attribute log.



20
21
22
# File 'lib/dango/tasks/dango_rake.rb', line 20

def log
  @log
end

Instance Method Details

#check_dango_connectObject

サーバーへの通信を使ったチェック



138
139
140
141
142
143
144
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
# File 'lib/dango/tasks/dango_rake.rb', line 138

def check_dango_connect()
  require 'dango/tester/dango_tester_client'
  
  # コンフィグから check_dango_process_cmd を取得
  config = YAML.load(open("#{RAILS_ROOT}/config/dango/#{ENV['RAILS_ENV']}.yml", "rb"){|fh| fh.read})
  
  serv_info = {}
  serv_info["host"] = config['network']['host'] || 'localhost'
  serv_info["port"] = config['network']['port'] || 15000
  serv_info["log_file"] = CheckConnectLogFile
  serv_info["log_level"] = Logger::DEBUG
  serv_info["log_max_size"] = 10000000
  serv_info["log_shift_age"] = 1
  
#  pp serv_info
  
  sid = nil
  
  begin
    tester = DangoTesterClient.new # 開始
    tester1 = nil
    timeout(12) do
      tester1 = tester.new_client("tester1", serv_info) # テスター1
      
      10.times do |i|
        sleep 1
        sid = tester1.sid.deep_dup
        tester1.logger.warn "count=#{i} sid=#{sid}"
        break if sid
      end
    end
  rescue TimeoutError
    sid = nil
    ret_kill "DangoTesterClient.TimeoutError" if $is_verbose
  ensure
    tester1.dango_client_close if tester1.respond_to?(:dango_client_close)
    tester1 = nil
    tester.gc_thread_stop
  end
  
  puts_verbose "sid=#{sid.inspect}"
  
  if sid
    is_alive_server = true
  else
    is_alive_server = false
  end
  
  is_alive_server
end

#check_exist_dango_process(pid) ⇒ Object

pidのプロセスがあるかどうかのチェック



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/dango/tasks/dango_rake.rb', line 51

def check_exist_dango_process(pid)
  puts_verbose "check_exist_dango_process(pid=#{pid})"
  
  # そのpidのプロセスがあるかのチェック
  is_pid_exist = nil
  
  if RUBY_PLATFORM == 'i386-mswin32'
    # WbemからProcessIDを取得
    require "win32ole"
    begin
      n_locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
      n_service = n_locator.ConnectServer
    rescue
      puts_verbose "failed connect to Wbem:#{$!.inspect}"
      return
    end
    
    set = n_service.ExecQuery("select Caption, ProcessID from Win32_Process where ProcessID = #{pid}")
    set.each do |one|
      puts_verbose(sprintf("Win32_Process %8d %s", one.ProcessID, one.Caption))
      if one.ProcessID == pid
        is_pid_exist = true
      end
    end
    
  else ## i386-mswin32以外
    is_pid_exist = FileTest.exist?("/proc/#{pid}")
  end
  
  if is_pid_exist
    puts_verbose "dango_process is exist."
  else
    puts_verbose "dango_process is not exist."
  end
  
  is_pid_exist
end

#check_verbose_modeObject

verboseモードのフラグを立てる処理



23
24
25
# File 'lib/dango/tasks/dango_rake.rb', line 23

def check_verbose_mode()
  $is_verbose = (ENV["verbose"] == "true" || ENV["verbose"] == "on") ? true : false
end

#drb_call(method_name, arg = nil) ⇒ Object

drbからのサーバー呼び出し



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/dango/tasks/dango_rake.rb', line 190

def drb_call(method_name, arg = nil)
  config = YAML.load(open("#{RAILS_ROOT}/config/dango/#{ENV['RAILS_ENV']}.yml", "rb"){|fh| fh.read})
  
  raise("backdoor_run_drb_server is false.") if !config['server']['backdoor_run_drb_server']
  
  if ENV['url']
    drb_uri = ENV['url']
  else
    drb_uri = config['server']['backdoor_run_drb_url']
  end
  puts_verbose drb_uri
  
  ret = nil
  begin
    timeout(3) do
      drb_obj = DRbObject.new_with_uri(drb_uri)
      ret = drb_obj.__send__(method_name.to_s, arg)
    end
  rescue Exception
    raise("DRbError:#{$!.class} #{$!.message} #{$!.backtrace.pretty_inspect}")
  end
  ret
end

#get_dango_pidObject

pid保存ファイルの読み出し



40
41
42
43
44
45
46
47
48
# File 'lib/dango/tasks/dango_rake.rb', line 40

def get_dango_pid()
  begin
    pid = open("tmp/pids/dango.#{ENV['RAILS_ENV']}.pid", "rb"){|fh| fh.read }.to_i
  rescue
    pid = nil
  end
  puts_verbose "pid=#{pid.inspect}"
  pid
end

#get_trouble_status(config, pid = nil) ⇒ Object

落ちた時の情報収集処理



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
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
294
295
296
297
298
299
300
# File 'lib/dango/tasks/dango_rake.rb', line 215

def get_trouble_status(config, pid = nil)
  # フォルダ作成
  time_str = Time.now.strftime('%Y%m%d_%H%M%S')
  dir_name = "log/#{time_str}_#{ENV['RAILS_ENV']}"
  FileUtils.mkdir(dir_name) rescue nil
  
  # サーバーログの保管
  old_file = config['server']['log_file'].to_s
  if File.file?(old_file)
    new_file = "#{dir_name}/#{File.basename(old_file)}"
    puts_verbose "copy #{old_file} #{new_file}"
    FileUtils.copy(old_file, new_file) rescue nil
  end
  
  # 接続ログの保管
  if File.file?(CheckConnectLogFile)
    new_file = "#{dir_name}/#{File.basename(CheckConnectLogFile)}"
    puts_verbose "copy #{CheckConnectLogFile} #{new_file}"
    FileUtils.copy(CheckConnectLogFile, new_file) rescue nil
  end
  
  # スレッド情報と排他処理情報収集
  begin
    open("#{dir_name}/thread_status.txt", "wb") do |fh|
      
      fh.puts "==== log"
      fh.puts log
      
      fh.puts "==== get_process_info"
      fh.puts get_process_info(pid)
      
      fh.puts "==== get_server_info"
      fh.puts drb_call(:_monitor_get_server_info).pretty_inspect
      
      fh.puts "==== thread_list"
      fh.puts drb_call(:_monitor_thread_status).pretty_inspect
      
      fh.puts "==== mutex_list"
      fh.puts drb_call(:_monitor_mutex_status).pretty_inspect
      
      fh.puts "==== get_socket_list"
      fh.puts drb_call(:_monitor_get_socket_list).pretty_inspect
      
      fh.puts "==== get_shared"
      fh.puts drb_call(:_monitor_get_shared).pretty_inspect
      
    end
  rescue Exception
    puts_verbose "failed get thread_status."
  end
  
  # モード変更
  FileUtils.chmod_R(0777, [dir_name]) rescue nil
  
  # ファイルの圧縮
  begin
    require "zip/zip"
    can_zip = true
  rescue LoadError
    can_zip = false
  end
  
  if can_zip
    outzipfile = "log/#{time_str}_#{ENV['RAILS_ENV']}.zip"
    
    files = []
    Find.find(dir_name) do |filename|
      if FileTest::readable?(filename) and FileTest::file?(filename)
        files.push(filename)
      end
    end
    
    Zip::ZipOutputStream.open(outzipfile) do |zos|
      files.each do |name|
        zos.put_next_entry(name)
        File.open(name, "rb"){|f| zos.puts(f.read) }
      end
    end
    
    FileUtils.rm_f(files) rescue nil
    FileUtils.remove_entry(dir_name, true) rescue nil
    
    FileUtils.chmod_R(0666, [outzipfile]) rescue nil
  end
  
end

#puts_noverbose(str) ⇒ Object

出力+ログ



28
29
30
31
# File 'lib/dango/tasks/dango_rake.rb', line 28

def puts_noverbose(str)
  @log += "#{Time.now_to_s} #{str.to_s}\n"
  puts str.to_s
end

#puts_verbose(str) ⇒ Object

出力+ログ(verbose)



34
35
36
37
# File 'lib/dango/tasks/dango_rake.rb', line 34

def puts_verbose(str)
  @log += "#{Time.now_to_s} #{str.to_s}\n"
  puts str.to_s if $is_verbose
end

#stop_process(pid) ⇒ Object

プロセス停止



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/dango/tasks/dango_rake.rb', line 90

def stop_process(pid)
  puts_verbose "stop process (pid=#{pid})"
  
  if RUBY_PLATFORM == 'i386-mswin32'
    # WbemからProcessIDを取得
    require "win32ole"
    begin
      n_locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
      n_service = n_locator.ConnectServer
    rescue
      puts_verbose "failed connect to Wbem:#{$!.inspect}"
      return
    end
    
    set = n_service.ExecQuery("select Caption, name, ProcessID from Win32_Process where ProcessID = '#{pid}'")
    set.each do |process|
      puts_verbose "stopping #{process.Caption} #{process.name} #{process.ProcessID}"
      process.Terminate 0
    end
    
  else ## i386-mswin32以外
#    system("kill #{pid}")
    ret_kill = Process.kill("TERM", pid) rescue nil
    puts_verbose "kill TERM ret_kill=#{ret_kill.inspect}"
    
    
    # きちんと落ちたかチェック
    is_kill = false
    20.times do
      sleep 1
      if !File.exist?("/proc/#{pid}")
        is_kill = true
        break
      end
    end
    
    if !is_kill # 落ちていなければ、-9で終了
#      system("kill -9 #{pid}")
      begin
        Process.kill("KILL", pid)
      rescue
        puts_verbose "process pid(#{pid}) is exist. but failed kill -9 #{pid}"
      end
    end
  end
end