summaryrefslogtreecommitdiff
path: root/app/services/job_scheduler.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/job_scheduler.rb')
-rw-r--r--app/services/job_scheduler.rb50
1 files changed, 50 insertions, 0 deletions
diff --git a/app/services/job_scheduler.rb b/app/services/job_scheduler.rb
new file mode 100644
index 00000000000..01c9bdbcc84
--- /dev/null
+++ b/app/services/job_scheduler.rb
@@ -0,0 +1,50 @@
+class JobScheduler
+
+ attr_reader :ident
+ def initialize(ident = nil)
+ @ident = ident
+ end
+
+ def start_work!
+ while run_next_job
+ end
+ end
+
+ private
+ def run_next_job
+ ActiveRecord::Base.transaction do
+ job = dequeue_job!
+
+ unless job
+ Rails.logger.info "Nothing to do."
+ return false
+ end
+
+ log = JobLog.new(job: job, scheduler: ident)
+
+ # Note that we may want to trade full consistency over
+ # making sure the database transactions are short.
+ #
+ # We could reschedule the job here and commit
+ # and only then execute the job.
+
+ begin
+ JobWorker.new(job).perform
+ ensure
+ log.save!
+ reschedule(job)
+ end
+
+ return true
+ end
+ end
+
+ def dequeue_job!
+ Job.lock('FOR UPDATE SKIP LOCKED').where('scheduled_for <= NOW()').order(:scheduled_for, :id).limit(1).first
+ end
+
+ def reschedule(job)
+ job.scheduled_for = Time.now() + 10.seconds
+ job.save!
+ end
+end