Class: Job

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/background_fu/job.rb

Overview

Example:

job = Job.enqueue!(MyWorker, :my_method, "my_arg_1", "my_arg_2")

Defined Under Namespace

Modules: BonusFeatures, Callbacks

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) cleanup_finished_jobs

Delete finished jobs that are more than a week old.



80
81
82
83
# File 'lib/background_fu/job.rb', line 80

def self.cleanup_finished_jobs
  logger.info "BackgroundFu: Cleaning up finished jobs."
  Job.destroy_all(["state='finished' and updated_at < ?", 1.week.ago])
end

+ (Object) enqueue!(worker_class, worker_method, *args)



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/background_fu/job.rb', line 17

def self.enqueue!(worker_class, worker_method, *args)
  job = create!(
    :worker_class  => worker_class.to_s,
    :worker_method => worker_method.to_s,
    :args          => args
  )

  logger.info("BackgroundFu: Job enqueued. Job(id: #{job.id}, worker: #{worker_class}, method: #{worker_method}, argc: #{args.size}).")
  
  job
end

+ (Object) generate_state_helpers



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

def self.generate_state_helpers
  states.each do |state_name|
    define_method("#{state_name}?") do
      state == state_name
    end

    # Job.running => array of running jobs, etc.
    self.class.send(:define_method, state_name) do
      find_all_by_state(state_name, :order => "id desc")
    end
  end
end

Instance Method Details

- (Object) ensure_worker



70
71
72
73
74
75
76
77
# File 'lib/background_fu/job.rb', line 70

def ensure_worker
  self.progress = @worker.instance_variable_get("@progress")
  save!
rescue StaleObjectError
  # Ignore this exception as its only purpose is
  # not allowing multiple daemons execute the same job.
  logger.info("BackgroundFu: Race condition handled (It's OK). Job(id: #{id}).")
end

- (Object) get_done!

Invoked by a background daemon.



30
31
32
33
34
35
36
37
# File 'lib/background_fu/job.rb', line 30

def get_done!
  initialize_worker
  invoke_worker
rescue Exception => e
  rescue_worker(e)
ensure
  ensure_worker
end

- (Object) initialize_worker



52
53
54
55
56
# File 'lib/background_fu/job.rb', line 52

def initialize_worker
  update_attributes!(:started_at => Time.now, :state => "running")
  @worker = worker_class.constantize.new
  logger.info("BackgroundFu: Job initialized. Job(id: #{id}).")
end

- (Object) invoke_worker



58
59
60
61
62
# File 'lib/background_fu/job.rb', line 58

def invoke_worker
  self.result = @worker.send(worker_method, *args)
  self.state  = "finished"
  logger.info("BackgroundFu: Job finished. Job(id: #{id}).")
end

- (Object) rescue_worker(exception)



64
65
66
67
68
# File 'lib/background_fu/job.rb', line 64

def rescue_worker(exception)
  self.result = [exception.message, exception.backtrace.join("\n")].join("\n\n")
  self.state  = "failed"
  logger.info("BackgroundFu: Job failed. Job(id: #{id}).")
end

- (Object) restart!

Restart a failed job.



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/background_fu/job.rb', line 40

def restart!
  if failed? 
    update_attributes!(
      :result     => nil, 
      :progress   => nil, 
      :started_at => nil, 
      :state      => "pending"
    )
    logger.info("BackgroundFu: Job restarted. Job(id: #{id}).")
  end
end

- (Object) setup_priority

Default priority is 0. Jobs will be executed in descending priority order (negative priorities allowed).



106
107
108
109
110
# File 'lib/background_fu/job.rb', line 106

def setup_priority
  return unless priority.blank?
  
  self.priority = 0
end

- (Object) setup_start_at

Job will be executed after this timestamp.



113
114
115
116
117
# File 'lib/background_fu/job.rb', line 113

def setup_start_at
  return unless start_at.blank?
  
  self.start_at = Time.now
end

- (Object) setup_state



99
100
101
102
103
# File 'lib/background_fu/job.rb', line 99

def setup_state
  return unless state.blank?

  self.state = "pending" 
end