Sha256: a0ccb1cd7c033f8bd642293f8ba3976722fdfdcf3e59e5d90a2a35f1a2bb2f62

Contents?: true

Size: 1.7 KB

Versions: 1

Compression:

Stored size: 1.7 KB

Contents

require 'stringio'
require 'logger'

module Crono
  class Job
    include Logging

    attr_accessor :performer
    attr_accessor :period
    attr_accessor :last_performed_at
    attr_accessor :job_log
    attr_accessor :job_logger

    def initialize(performer, period)
      self.performer, self.period = performer, period
      self.job_log = StringIO.new
      self.job_logger = Logger.new(job_log)
      @semaphore = Mutex.new
    end

    def next
      next_time = period.next(since: last_performed_at)
      next_time.past? ? period.next : next_time
    end

    def description
      "Perform #{performer} #{period.description}"
    end

    def job_id
      description
    end

    def perform
      log "Perform #{performer}"
      self.last_performed_at = Time.now

      Thread.new do
        begin
          performer.new.perform
        rescue Exception => e
          log "Finished #{performer} in %.2f seconds with error: #{e.message}" % (Time.now - last_performed_at)
          log e.backtrace.join("\n")
        else
          log "Finished #{performer} in %.2f seconds" % (Time.now - last_performed_at)
        ensure
          save
        end
      end
    end

    def save
      @semaphore.synchronize do
        log = model.reload.log || ""
        log << job_log.string
        job_log.truncate(job_log.rewind)
        model.update(last_performed_at: last_performed_at, log: log)
      end
    end

    def load
      self.last_performed_at = model.last_performed_at
    end

  private
    def log(message)
      @semaphore.synchronize do
        logger.info message
        job_logger.info message
      end
    end

    def model
      @model ||= Crono::CronoJob.find_or_create_by(job_id: job_id)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
crono-0.7.0 lib/crono/job.rb