nobilik
nobilik

Reputation: 736

How to run cyclic background process in Ruby-on-Rails?

I have some methods that works with API of third party app. To do it on button click is no problem, but it should be permanent process.

How to run them background? And how to pause the cycle for make some other works with same API and resume the cycle after the job is done.

Now I read about ActiveJob, but its has time dependences only...

UPDATE

I've tried to make it with whenever and sidekiq, task runs, but it do nothing. Where to look for logs I can't understand.

**schedule.rb**

every 1.minute do
  runner "UpdateWorker.perform_async"
end

**update_worker.rb**

    class UpdateWorker
      include Sidekiq::Worker
      include CommonMods

      def perform
        logger.info "Things are happening."
        logger.debug "Here's some info: #{hash.inspect}"
        myMethod
      end
      def myMethod
            ....
            ....
            ....
      end
   end

It's not exactly what I need, but better then nothing. Can somebody explain me with examples?

UPDATE 2 After manipulating with code it's absolutely necessary to restart sidekiq . With this problem is solved, but I'm not sure that this is the best way.

Upvotes: 0

Views: 570

Answers (4)

theDrifter
theDrifter

Reputation: 1706

I dont know ActiveJobs, but I can recommend the whenever gem to create cron (periodic background) jobs. Basically you end up writing a rake tasks. Like this:

desc 'send digest email'
 task send_digest_email: :environment do
  # ... set options if any
  UserMailer.digest_email_update(options).deliver!
end

I never added a rake task to itself but for repeated processing you could do somehow like this (from answers to this specific question)

Rake::Task["send_digest_email"].execute

Upvotes: 0

Aetherus
Aetherus

Reputation: 8908

You can define a job which enqueues itself:

class MyJob < ActiveJob::Base
  def perform(*args)
    # Do something unless some flag is raised
  ensure
    self.class.set(wait: 1.hour).perform_later(*args)
  end
end

Upvotes: 1

Vasfed
Vasfed

Reputation: 18504

Just enqueue next execution in ensure section after job completes after checking some flag that indicates that it should.

Also i recommend adding some delay there so that you don't end up with dead loop on some error inside job

Upvotes: 0

Marcus Ilgner
Marcus Ilgner

Reputation: 7241

There are several libraries to schedule jobs on a regular basis. For example you could use to sidekiq-cron to run a job every minute.

If you want to pause it for some time, you could set a flag somewhere (Redis/database/file) and skip execution as long it is detected.

On a somewhat related note: don't use sidetiq. It was really great but it's not maintained anymore and has incompatibilities to current Sidekiq versions.

Upvotes: 0

Related Questions