Monitoring rake test - ruby-on-rails

I have a rake task running daily at a specified time, I just want a alert email(or sms) when it fails (or even the entire rake task hangs or even the server hangs). Earlier I was using AlertGrid, I will send a signal to alertgrid at the end of the rake task, and configured alertgrid in such a way to notify me in the absence of signal, but I cannot continue with it alertgrid now, does anyone know any alternative approach for this problem?
Or any other method to monitor rake task and intimate unsuccessful operation of rake task?
Thx.

This might not be the best approach but you could have your rake task relegate the actual job to Resque and just schedule your rake task via a cron job.
Resque has a very nice web-admin that shows off all failed jobs per queue; as for notification you could possibly modify Resque to send out an email (and/or process a different job to send out texts via the API of whatever SMS-provider you use).

Related

If I use Heroku scheduler, do I still need delayed job?

I'm a little confused about this. I have a couple of tasks that I would like to run asynchronously, for example my inventory sync integration. For this I have implemented delayed job, but I realize that I need to run rake jobs:work on Heroku for this. I can use the Heroku scheduler to run this rake task every 10 minutes. My question is; if I create rake tasks to run i.e. my inventory sync method, do I still need delayed job? My understanding is that heroku scheduler kicks off 'one off dynos'.
Instead of using delayed job, could I not just kick off the sync method directly since a separate dyno is used anyway? What is the added value of delayed job here?
Heroku's Scheduler replaces what cron would handle on a typical server. Delayed Job or Sidekiq are for processing jobs asynchronously from your app, not a timed schedule.
The reason you use a worker & run these jobs on the back-end is so that your server can return a response as soon as is possible rather than making the user wait for some potentially unnecessarily long running process to finish (lots of queries, outbound e-mail, external API requests, etc.).
Ex, scheduler can run analytics or updates from a script every hour or day, but delayed job can not.

Rails Async Active Job doesn't execute code, while inline does

Does the :async queue adapter actually do anything?
:inline, which is what is default in Rails 4, processes jobs built with ActiveJob, uh... inline, in the current execution thread. Async, shouldn't. It should use the ConnectionPool to not run it in the current thread, and that's ideally what would be happening. It'd run perform outside of the current execution thread.
But nothing executes it.
I've pored through the docs, and the only thing I can fathom is is that :async, unlike :inline, doesn't execute tasks, and expects you to build a system around execution locally. I have to manually perform perform on all jobs in order to get them to execute locally. When I set the adapter to :inline, it works just fine without having to execute.
Is there some configuration issue I'm missing that's preventing async from working correctly (like ActionCable?).
Does it not work if executed from a rake task (or the console?).
It works fine with :sidekiq/:resque, but I don't want to be running these locally all the time.
Rails by default comes with an "immediate runner" queuing implementation. That means that each job that has been enqueued will run immediately.
This is kind of what's cueing me in there being something wrong. I have jobs that are sitting in a queue somewhere that just don't run. What could be stopping this?
This is what I discovered. With the advent of concurrent-ruby, rake tasks aren't set up to handle this.
If you read in the documentation, it says with :async, it's cleared out of memory when the process ends.
Rails itself only provides an in-process queuing system, which only
keeps the jobs in RAM. If the process crashes or the machine is reset,
then all outstanding jobs are lost with the default async back-end.
Rake processes end when they're over. So, if you're doing any sort of data changes, rake tasks won't be open long enough to run a job, which is why they run :inline just fine, but not :async.
So, I haven't figured out a solution to keep rake tasks open long enough to run something :async (and keep the app :async the entire time). I have to switch it to :inline to run tasks, and then back to :async when I'm done for the rest of my jobs. It's why it works fine with :sidekiq or :resque, because those applications keep the job information in memory and do not release when the rake task is over.
In order for rake tasks to work with :async locally, there's not much you can do other than run tasks as :inline if you're local until rake (as a task runner) understands how to stay open while asynchronous tasks have been launched (or not). As a development only feature, this isn't really high priority, but, if you're bashing your head on the table not understanding why :async by default tasks that run jobs won't actually run, that's why.
Here's what you can put at the end of a rake task to wait for the AsyncAdapter to finish processing before exiting the rake task:
if Rails.configuration.active_job.queue_adapter == :async
executor =
ActiveJob::Base._queue_adapter.instance_eval do
#scheduler.instance_eval { #async_executor }
end
sleep(0.1) while executor.scheduled_task_count > executor.completed_task_count
end

What is the best way to run a long task on Heroku with Ruby On Rails?

I am looking for the best way to run a very long task in Heroku.
I use Ruby On Rails for my web application and I have a very long task that I want to run it every week on Sunday during the night. It takes around 15~20 minutes. I already have Rufus-Scheduler, but I am not sure it is the most effective solution.
I also find something about Backgrounding Tasks in Heroku with Delayed Job. But is it the best way to handle it ?
Thanks.
This is what I use for a job that I run every night: https://devcenter.heroku.com/articles/scheduler
It works really well if your job is configured as a rake task. The guide at the link shows you how to configure everything and even addresses long-running jobs.
Heroku does not recommend to run long-running jobs with Heroku Scheduler.
Heroku says,
Scheduled jobs are meant to execute short running tasks or enqueue longer running tasks into a background job queue. Anything that takes longer than a couple of minutes to complete should use a worker dyno to run.
So, in my opinion, the best approach would be to use Heroku Scheduler to run rake task for every kind of job (short or long) but if a task takes longer than a couple of minutes then I would simply create a Background Job within that rake task. That way the scheduler will never run longer than a couple of minutes.

Find out whether specific rake task is currently running

Is there any way to find out whether particular rake task is currently running from Rails controller for example? I have an extensive rake task, which takes 5-6 hours to finish.
I need to see status of that rake task from frontend web interface, like:
Task "some operation" is running...
Also it would be nice to be able to hard stop / run that rake task from within frontend web interface.
If found Railscast devoted to it, but the method described there allows only to run rake task from controller, but not to stop/see its status.
If your job is taking 5-6 hours to complete, you must run it in background. To run long running jobs in background you can use one of these:
Resque
Sidekiq
And for tracking status of your jobs, you can use corresponding status tracking gems:
ResqueStatus
SidekiqStatus
Personally, I prefer sidekiq for its efficiency.
NOTE: All the above mentioned gems has good enough docs. Kindly refer to those.

Does Rake task need to run in the background using Resque?

I have this code in my rake task. It seems overkill, since the rake task is already being run as a cron job. I think I can safely take it out of Resque and run it directly, but not sure if I missed something.
desc "update daily sales"
task :daily_sales => :environment do
Resque.enqueue(DailySaleService.perform)
end
Yes, it's overkill. There is no reason to use background processing for a rake task; you use background processing to remove heavy lifting from the HTTP request/response cycle to provide users with a better front-end experience. It won't provide any value in a rake task.

Resources