Class: TengineJobAgent::Run

Inherits:
Object
  • Object
show all
Includes:
CommandUtils
Defined in:
lib/tengine_job_agent/run.rb

Constant Summary

Constants included from CommandUtils

CommandUtils::DEFAULT_CONFIG

Instance Method Summary collapse

Methods included from CommandUtils

included

Constructor Details

#initialize(logger, args, config = {}) ⇒ Run

Returns a new instance of Run.



9
10
11
12
13
14
15
16
17
# File 'lib/tengine_job_agent/run.rb', line 9

def initialize(logger, args, config = {})
  @logger = logger
  @pid_output = STDOUT
  @error_output = STDERR
  @args = args
  @config = config
  @timeout       = (config[:timeout      ] || ENV["MM_SYSTEM_AGENT_RUN_TIMEOUT"      ] || 600).to_i # seconds
  @timeout_alert = (config[:timeout_alert] || ENV["MM_SYSTEM_AGENT_RUN_TIMEOUT_ALERT"] || 30 ).to_i # seconds
end

Instance Method Details

#pid_pathObject



52
53
54
# File 'lib/tengine_job_agent/run.rb', line 52

def pid_path
  File.expand_path("pid_for_#{Process.pid}", @config['log_dir'])
end

#processObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/tengine_job_agent/run.rb', line 19

def process
  validate_environment
  line = nil
  process_spawned = false
  setup_pid_file do |pid_path|
    begin
      timeout(@timeout) do #タイムアウト(秒)
        @logger.info("watchdog process spawning for #{@args.join(' ')}")
        pid = spawn_watchdog(pid_path) # watchdogプロセスをspawnで起動
        @logger.info("watchdog daemon invocation process spawned. PID: #{pid.inspect}")
        File.open(pid_path, "r") do |f|
          sleep(0.1) until line = f.gets
          process_spawned = true
          @logger.info("watchdog process returned first result: #{line.inspect}")
          if line =~ /\A\d+\n?\Z/ # 数字と改行のみで構成されるならそれはPIDのはず。
            @pid_output.puts(line.strip)
            @logger.info("return PID: #{line.strip}")
          else
            f.rewind
            msg = f.read
            @logger.error("error occurred:\n#{msg}")
            @error_output.puts(msg)
            return false
          end
        end
      end
    rescue Timeout::Error => e
      @error_output.puts("[#{e.class.name}] #{e.message}")
      raise e # raiseしたものはTengineJobAgent::Run.processでloggerに出力されるので、ここでは何もしません
    end
  end
end

#setup_pid_fileObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/tengine_job_agent/run.rb', line 56

def setup_pid_file
  path = self.pid_path
  @logger.info("pid file creating: #{path}")
  File.open(path, "w"){ } # ファイルをクリア
  @logger.info("pid file created: #{path}")
  begin
    res = yield(path)
    File.delete(path) if File.exist?(path)
    return res
  rescue => e
    @logger.warn("pid file #{path.inspect} is not deleted cause of #{e.class.name}")
    raise
  end
end

#spawn_watchdog(pid_path) ⇒ Object

引数にpid_pathを渡してwatchdogを起動します。戻り値は起動したwatchdogのPIDです



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/tengine_job_agent/run.rb', line 72

def spawn_watchdog(pid_path)
  # http://doc.ruby-lang.org/ja/1.9.2/method/Kernel/m/spawn.html を参考にしています
  args = @args # + [{:out => stdout_w}] #, :err => stderr_w}]
  watchdog = File.expand_path("../../bin/tengine_job_agent_watchdog", File.dirname(__FILE__))
  # args = [RbConfig.ruby, watchdog, pid_path, *(@args + [{:out => stdout_w, :err => stderr_w}])]
  args = [RbConfig.ruby, watchdog, pid_path, *@args]
  @logger.info("Process.spawn(*#{args.inspect})")
  pid = Process.spawn(*args)
  # ただしこのpidとして起動したプロセスはデーモンプロセスを起動するためのプロセスであり、
  # 即座に終了してします
  @logger.info("spawned watchdog: #{pid}")
  @logger.debug("spawned watchdog:" << `ps aux | grep tengine_job_agent_watchdog | grep -v grep`)
  return pid
end

#validate_environmentObject

ジョブ実行時に使用されるRubyが1.8系の場合でもtengine_job_agent_runがエラーを起こさない



88
89
90
91
92
93
94
# File 'lib/tengine_job_agent/run.rb', line 88

def validate_environment
  if RUBY_VERSION >= "1.9.2"
    @logger.info("RUBY_VERSION is #{RUBY_VERSION}")
  else
    raise "RUBY_VERSION must be >= 1.9.2 but was #{RUBY_VERSION}"
  end
end