Class: Procrastinator::TaskWorker

Inherits:
Object
  • Object
show all
Defined in:
lib/procrastinator/task_worker.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id: nil, run_at: nil, initial_run_at: nil, expire_at: nil, attempts: 0, timeout: nil, max_attempts: nil, last_fail_at: nil, last_error: nil, task:) ⇒ TaskWorker

Returns a new instance of TaskWorker.

Raises:



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/procrastinator/task_worker.rb', line 7

def initialize(id: nil,
               run_at: nil,
               initial_run_at: nil,
               expire_at: nil,
               attempts: 0,
               timeout: nil,
               max_attempts: nil,
               last_fail_at: nil,
               last_error: nil,
               task:)
   @id             = id
   @run_at         = run_at.to_i
   @initial_run_at = initial_run_at.to_i
   @expire_at      = expire_at.nil? ? nil : expire_at.to_i
   @task           = YAML.load(task)
   @attempts       = attempts
   @max_attempts   = max_attempts
   @timeout        = timeout
   @last_fail_at   = last_fail_at
   @last_error     = last_error

   raise(MalformedTaskError.new('given task does not support #run method')) unless @task.respond_to? :run
   raise(ArgumentError.new('timeout cannot be negative')) if timeout && timeout < 0
end

Instance Attribute Details

#attemptsObject (readonly)

Returns the value of attribute attempts.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def attempts
  @attempts
end

#expire_atObject (readonly)

Returns the value of attribute expire_at.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def expire_at
  @expire_at
end

#idObject (readonly)

Returns the value of attribute id.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def id
  @id
end

#initial_run_atObject (readonly)

Returns the value of attribute initial_run_at.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def initial_run_at
  @initial_run_at
end

#last_errorObject (readonly)

Returns the value of attribute last_error.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def last_error
  @last_error
end

#last_fail_atObject (readonly)

Returns the value of attribute last_fail_at.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def last_fail_at
  @last_fail_at
end

#run_atObject (readonly)

Returns the value of attribute run_at.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def run_at
  @run_at
end

#taskObject (readonly)

Returns the value of attribute task.



5
6
7
# File 'lib/procrastinator/task_worker.rb', line 5

def task
  @task
end

Instance Method Details

#expired?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/procrastinator/task_worker.rb', line 75

def expired?
   !@expire_at.nil? && Time.now.to_i > @expire_at
end

#successful?Boolean

Returns:

  • (Boolean)


63
64
65
66
67
68
69
# File 'lib/procrastinator/task_worker.rb', line 63

def successful?
   if !expired? && @attempts <= 0
      raise(RuntimeError, 'you cannot check for success before running #work')
   end

   @last_error.nil? && @last_fail_at.nil?
end

#to_hashObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/procrastinator/task_worker.rb', line 79

def to_hash
   {id:             @id,
    run_at:         @run_at,
    initial_run_at: @initial_run_at,
    expire_at:      @expire_at,
    attempts:       @attempts,
    last_fail_at:   @last_fail_at,
    last_error:     @last_error,
    task:           YAML.dump(@task)}
end

#too_many_fails?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/procrastinator/task_worker.rb', line 71

def too_many_fails?
   !@max_attempts.nil? && @attempts >= @max_attempts
end

#workObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/procrastinator/task_worker.rb', line 32

def work
   @attempts += 1

   begin
      raise(TaskExpiredError.new("task is over its expiry time of #{@expire_at}")) if expired?

      Timeout::timeout(@timeout) do
         @task.run
      end

      try_hook(:success)
      @last_error   = nil
      @last_fail_at = nil
   rescue StandardError => e
      @last_fail_at = Time.now.to_i

      if too_many_fails? || expired?
         try_hook(:final_fail, e)

         @run_at     = nil
         @last_error = "#{expired? ? 'Task expired' : 'Task failed too many times'}: #{e.backtrace.join("\n")}"
      else
         try_hook(:fail, e)

         @last_error = 'Task failed: ' + e.backtrace.join("\n")

         reschedule
      end
   end
end