summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/models/job.rb3
-rw-r--r--app/models/job_log.rb13
-rw-r--r--app/services/job_scheduler.rb50
-rw-r--r--app/workers/job_worker.rb12
4 files changed, 78 insertions, 0 deletions
diff --git a/app/models/job.rb b/app/models/job.rb
new file mode 100644
index 00000000000..4e7e098d854
--- /dev/null
+++ b/app/models/job.rb
@@ -0,0 +1,3 @@
+class Job < ApplicationRecord
+ has_many :job_logs
+end
diff --git a/app/models/job_log.rb b/app/models/job_log.rb
new file mode 100644
index 00000000000..5296f429320
--- /dev/null
+++ b/app/models/job_log.rb
@@ -0,0 +1,13 @@
+class JobLog < ApplicationRecord
+ belongs_to :job
+
+ after_initialize do |log|
+ log.started_at = Time.now()
+ end
+
+ before_create do
+ if self.finished_at.blank?
+ self.finished_at = Time.now()
+ end
+ end
+end
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
diff --git a/app/workers/job_worker.rb b/app/workers/job_worker.rb
new file mode 100644
index 00000000000..19b3d015096
--- /dev/null
+++ b/app/workers/job_worker.rb
@@ -0,0 +1,12 @@
+class JobWorker
+
+ attr_reader :job
+
+ def initialize(job)
+ @job = job
+ end
+
+ def perform
+ # Do nothing
+ end
+end