0

I have a use case where user schedules a 'command' from the web interface. The user also specifies the date and time the command needs to be triggred.

This is sequence of steps:

1.User schedules a command 'Restart Device' at May 31, 3pm.

2.This is saved in a database table called Command.

3.Now there needs to be a background job that needs to be triggered at this specified time to do something (make an api call, send email etc.)

4.Once job is executed, It is removed or marked done, until a new command is issued.

There could be multpile users concurrently performing the above sequence of steps.

Is delayed_job a good choice for above? I couldnt find an example as how to implement above using delayed job.

EDIT: the reason I was looking at delayed_job is because eventually I would need to leverage existing relational database

newbie
  • 1,023
  • 20
  • 46

2 Answers2

3

I would advise to use Sidekiq. With it you can use scheduled jobs to tell sidekiq when to perform the jobs.

Example : MyWorker.perform_at(3.hours.from_now, 'mike', 1)

EDIT : worker example

#app/workers/restart_device_worker.rb
class RestartDeviceWorker
  include Sidekiq::Worker

  def perform(params)
    # Do the job
    # ...
    # update in DB
  end
end

BTL
  • 4,311
  • 3
  • 24
  • 29
  • What about the feedback? I need to update a status in a relational database based on the execution as well as success of the job. Should that reside in sidekiq as well? – newbie Apr 30 '19 at 02:39
  • Yes you can totally do that ! I'll add an example. – BTL Apr 30 '19 at 08:47
  • One final question, i can post this as a separate question if needed.Can a rails webapp and sidekiqworker run in the same app. I am using passenger as my app server. whats the best practice. – newbie Apr 30 '19 at 17:57
  • Is there a way to run a custom-defined job via rails console at a specific time? So I don't have to create a one-time script into a code structure. It's just a one-time job to set some data during the weekend. – Jan Krupa Jan 24 '20 at 08:59
  • @JanKrupa of course : in the rails console, you do `MyWorker.perform_async(data: data)` or `perform_in`, `perform_at`, etc. – BTL Jan 24 '20 at 12:08
  • @BTL yes but I don't want to define MyWorker as a script in the rails app. And when I define it in a console, then the execution fails because of the unknown class. – Jan Krupa Jan 24 '20 at 12:25
1

see doc: https://blog.codeship.com/how-to-use-rails-active-job/ https://guides.rubyonrails.org/active_job_basics.html

If you are using Rails 5 then you have best option of ActiveJob(inbuilt feature)

Use ActiveJob

"Active Job – Make work happen later. Active Job is a framework for declaring jobs and making them run on a variety of queuing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really."

Active Job has built-in adapters for multiple queuing backends (Sidekiq, Resque, Delayed Job and others). You just need to tell them.

Scenario: I want to delete my story after 24 hours(1 day). Then we do create a job named "StoriesCleanupJob". Call this job at the time of the creation of story like below

StoriesCleanupJob.set(wait: 1.day).perform_later(story)

It will call the Job after 1 day.

class StoriesCleanupJob < ApplicationJob
  queue_as :default

  def perform(story)
      if story.destroy
            #put your own conditions like update the status and all, whatever you want to perform.
      end
  end
end
Pragya Sriharsh
  • 529
  • 3
  • 6
  • Thanks . Can I delete a future job after it's been queued if the end user changes his mind? – newbie Apr 30 '19 at 11:57
  • 1
    Yes you can. but for this you have to maintain JobID. Also check this link: https://stackoverflow.com/questions/21101253/how-to-delete-a-job-in-sidekiq – Pragya Sriharsh Apr 30 '19 at 12:05