Class: Tootsie::Tasks::JobTask

Inherits:
Object
  • Object
show all
Defined in:
lib/tootsie/tasks/job_task.rb

Constant Summary collapse

DEFAULT_MAX_RETRIES =
5
PROGRESS_NOTIFICATION_INTERVAL =
10.seconds
VALID_TYPES =
%w(video audio image).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ JobTask

Returns a new instance of JobTask.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/tootsie/tasks/job_task.rb', line 12

def initialize(attributes = {})
  attributes = attributes.with_indifferent_access
  @type = attributes[:type].to_s
  @retries_left = attributes[:retries_left] || DEFAULT_MAX_RETRIES
  @access_key = attributes[:access_key]
  @created_at = Time.now
  @notification_url = attributes[:notification_url]
  @params = attributes[:params]
  @logger = Application.get.logger
  @use_tasks_for_notifications = false  # TODO: Disabled for now, SQS does not preserve order
end

Instance Attribute Details

#access_keyObject

Returns the value of attribute access_key.



103
104
105
# File 'lib/tootsie/tasks/job_task.rb', line 103

def access_key
  @access_key
end

#created_atObject

Returns the value of attribute created_at.



102
103
104
# File 'lib/tootsie/tasks/job_task.rb', line 102

def created_at
  @created_at
end

#notification_urlObject

Returns the value of attribute notification_url.



104
105
106
# File 'lib/tootsie/tasks/job_task.rb', line 104

def notification_url
  @notification_url
end

#paramsObject

Returns the value of attribute params.



105
106
107
# File 'lib/tootsie/tasks/job_task.rb', line 105

def params
  @params
end

#retries_leftObject

Returns the value of attribute retries_left.



101
102
103
# File 'lib/tootsie/tasks/job_task.rb', line 101

def retries_left
  @retries_left
end

#typeObject

Returns the value of attribute type.



106
107
108
# File 'lib/tootsie/tasks/job_task.rb', line 106

def type
  @type
end

Instance Method Details

#attributesObject



91
92
93
94
95
96
97
98
99
# File 'lib/tootsie/tasks/job_task.rb', line 91

def attributes
  return {
    :type => @type,
    :notification_url => @notification_url,
    :retries_left => @retries_left,
    :access_key => @access_key,
    :params => @params
  }
end

#execute!Object



28
29
30
31
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
62
63
64
65
66
67
# File 'lib/tootsie/tasks/job_task.rb', line 28

def execute!
  @logger.info("Begin processing job: #{attributes.inspect}")
  notify!(:event => :started)
  begin
    result = nil
    elapsed_time = Benchmark.realtime {
      next_notify = Time.now + PROGRESS_NOTIFICATION_INTERVAL
      processor = Processors.const_get("#{@type.camelcase}Processor").new(@params)
      result = processor.execute! { |progress_data|
        if Time.now >= next_notify
          notify!(progress_data.merge(:event => :progress))
          next_notify = Time.now + PROGRESS_NOTIFICATION_INTERVAL
        end
      }
    }
    result ||= {}
    notify!({
      :event => :completed,
      :time_taken => elapsed_time
    }.merge(result))
  rescue Interrupt
    @logger.error "Job interrupted"
    notify!(:event => :failed, :reason => 'Cancelled')
    raise
  rescue Exception => exception
    @logger.error "Job failed with exception #{exception.class}: #{exception}\n" <<
      "#{exception.backtrace.map { |line| "#{line}\n" }.join}"
    if @retries_left > 0
      @retries_left -= 1
      @logger.info "Pushing job back on queue to retry it"
      notify!(:event => :failed_will_retry, :reason => exception.message)
      Application.get.task_manager.schedule(self)
    else
      @logger.error "No more retries for job, marking as failed"
      notify!(:event => :failed, :reason => exception.message)
    end
  else
    @logger.info "Completed job #{attributes.inspect}"
  end
end

#notify!(message) ⇒ Object

Notify the caller of this job with some message.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/tootsie/tasks/job_task.rb', line 70

def notify!(message)
  notification_url = @notification_url
  if notification_url
    message = message.merge(:signature => Client.generate_signature(@access_key)) if @access_key
    message_json = message.stringify_keys.to_json
    if @use_tasks_for_notifications
      Application.get.task_manager.schedule(
        Tasks::NotifyTask.new(:url => notification_url, :message => message_json))
    else
      # TODO: Retry on failure
      @logger.info "Notifying #{notification_url} with message: #{message_json}"
      begin
        HTTPClient.new.post(notification_url, message_json,
          'Content-Type' => 'application/json; charset=utf-8')
      rescue Exception => exception
        @logger.error "Notification failed with exception, ignoring it: #{exception.message}"
      end
    end
  end
end

#valid?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/tootsie/tasks/job_task.rb', line 24

def valid?
  return @type && VALID_TYPES.include?(@type)
end