Class: Lobster::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/lobster/job.rb

Constant Summary collapse

OPTIONS =
[:command, :delay, :max_duration, :user, :directory]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Job

Returns a new instance of Job.



7
8
9
10
11
# File 'lib/lobster/job.rb', line 7

def initialize(name)
  @name = name
  Lobster.logger.info "Job #{name} created."
  @pid = nil
end

Instance Attribute Details

#next_runObject

Returns the value of attribute next_run.



3
4
5
# File 'lib/lobster/job.rb', line 3

def next_run
  @next_run
end

Instance Method Details

#check_last_runObject



33
34
35
36
37
38
39
# File 'lib/lobster/job.rb', line 33

def check_last_run
  if @max_duration > 0 and Time.now - @last_run >= (@max_duration + @delay)*60
    Lobster.logger.error(
      "Job #{@name} has not run since #{@last_run}"
    )
  end
end

#destroyObject



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/lobster/job.rb', line 85

def destroy
  Thread.new do
    Lobster.logger.info "Job #{name} being destroyed."
    destroy_time = Time.now
    while running?
      sleep 60
      if ((delay = Time.now - destroy_time) > 60*60)
        Lobster.logger.warn "Job #{name} has not been destroyed after #{delay} seconds."
      end
    end
  end
end

#kill(sig) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/lobster/job.rb', line 73

def kill(sig)
  if @pid
    Lobster.logger.info "Killing job #{@name} with pid #{@pid}"
    if @user
      `sudo -inu #{@user} -- kill -s #{sig} #{@pid}`
    else
      Process.kill sig, @pid
    end
    Process.wait @pid
  end
end

#reload(options, lobster_dir) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/lobster/job.rb', line 13

def reload(options, lobster_dir)
  options[:delay] ||= 10
  options[:max_duration] ||= 0
  options[:directory] ||= lobster_dir

  OPTIONS.each do |opt|
    val = instance_variable_get "@#{opt}"
    if options[opt] != val
      Lobster.logger.info "Job #{opt} updated for #{@name}, was \"#{val}\", now \"#{options[opt]}\"" if val
      instance_variable_set "@#{opt}", options.delete(opt)
      # special case: reset @next_run if delay is updated
      @next_run = nil if opt == :delay and not running?
    end
  end

  @name ||= "<unnamed_job_#{@command.hash.abs}>"
  @next_run ||= Time.now + rand(@delay*60)
  @last_run ||= Time.now
end

#runObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/lobster/job.rb', line 58

def run
  begin
    create_pipes

    Lobster.logger.info "Starting job #{@name}"
    command_line = @user ? "sudo -nu #{@user} -- sh -lc 'cd #{@directory}; #{@command}'" : @command

    @pid = spawn(command_line, :out=>@wout, :err=>@werr, :chdir=> @directory)
  rescue Exception => e
    Lobster.logger.error "#{e}: error when starting job #{@name}"
    close_pipes
    @next_run = Time.now + 10
  end
end

#running?Boolean

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/lobster/job.rb', line 41

def running?
  return false if @pid.nil?
  if Process.wait @pid, Process::WNOHANG
    if $?.success?
      @last_run = Time.now
    else
      Lobster.logger.error "Job #{@name} Failed with status #{$?}"
    end
    @pid = nil
    close_pipes
    @next_run = Time.now + @delay*60
    false
  else
    true
  end
end