Ruby on Rails, callback, run a method later - ruby-on-rails

I need somekind of a callback for a function to be caled in 5 min after the create-method.
My situation:
The user logs in in my web-page, uploads some files (create-method is invoked), in 5 min should the files be on their way to be analyzed(in 5 min it should call the method, which just take the whole folder, where the files are stored and analysis it). That is why such things like typing rake jobs:work or using gem daemons and typing "RAILS_ENV=production script/delayed_job start" in the command line does not suit me.
I want to start my apllication as usual with rails s, log in, upload the files and it should work automatically that the files are analyzed.
As I understood once the jobs started they will continue run? I do not need this. I need just some methods run in 5 min after create method.
All this stuff with gem 'delayed_job_active_record' to qeue the jobs and daemons to start the workers seem too complicted for such an easy task.
So, is it possible using gem 'delayed_job_active_record' and gem daemons to start my application with rails s and everythings will be done automatically in background without me stopping an application and typing things in the commanline to run the delayed jobs?
Or is it possible to do without all thise complicated stuff?
I have already asked about delayed_jobs here and here.
Many thanks in advance.

Here is a post where it is described how to set up scheduling with delayedjob
Update 2015-07-06: link's broken and I can't find a cached version - see update below
If you can, I recommend looking into sidekiq which is a great message queue and even has built in scheduling. It does use redis though, so unless you already have redis deployed it will be a tiny bit of work.
Update
Here is a gist with a simple solution to scheduled and recurring jobs with delayedjob

Related

Where do I put a recurring script that updates database from api in rails

I have a Rails app set up with a model Account that should be updated every morning with data coming from an external API I'm calling (a CRM). Basically either I create new accounts in my app that I find in the CRM and some of the fields that are mapped with my columns, either I find the account if it already exists and I update it.
So far, I've been putting this code into the seeds.rb file and from Heroku, where the app is hosted, I set up a scheduler with the command : rails db:seed that runs periodically.
My issue is that I'm sure there is a better way of doing this. I've read about rake tasks but I did not quite understand how that applied to my case. Otherwise I thought of putting my method in the models/account.rb file as a self method. But I don't really know how I can invoke it in a rake command to allow me to set up a scheduler in Heroku.
Any idea on where would be the best place to put this method, and how to call it from command line?
Thanks in advance.
You can create a script directory in your project, and put your script from db/seeds.rb into this directory, maybe called update_accounts.rb. Then you can run it with
rails runner script/update_accounts.rb
and schedule that task in heroku. More info about rails runner here.
I would suggest using a background processor such as Sidekiq: https://github.com/mperham/sidekiq
Once using Sidekiq, you need a scheduler like https://github.com/moove-it/sidekiq-scheduler to make sure it happens periodically as you require.
This will become easier to maintain as your application grows and you need more workers. It also moves your scheduling into version control.

Ruby on rails tasks automation in Windows 7

I'm looking for a tool or gem or something to allow me to run ruby methods every certain time.
I've tried many ways to do this like backgroundRB, whenever and starling and workling, the main problem is that we have to automate the tasks in Windows 7, we can't use cron.
BackgroundRB is not being updated, so we can't install it in ROR 3.0.3 or 3.0.9
What I need to do is to monit an event, using rake from the outside takes too long to load and will produce a timeout in a secondary system, so i need to run the methods from the 'inside' without loading all the environment every time.
There are many articles about this, but most of them are not updated, so I need a current suggestion, thanks in advance
Why not use the built in Windows Task Scheduler and batch or VBScripts? Even powershell could work.

Rubygem God: Time limit configuration for process

I am using resque, resque-scheduler gems in my rails app. To monitor the working of resque workers, I am using God tool. I want to add such a god configuration, which will monitor the time of job running in the resque worker. If process execution exceeds the time limit, then it should restart the worker.
I read post at http://god.rubyforge.org/. However, couldn't peek the right code base for my requirement.
Any information will be highly appreciated.
Thanks.
You could do something where your job creates a pid file, which you can use the FileMtime condition in god to monitor. When the job is finished, it recreates the pid file, if the file is older than x, restart the process with god.
source: https://github.com/mojombo/god/blob/856d321fb135a0b453046e99c266231681bd5ffe/lib/god/conditions/file_mtime.rb
Edit: Added github source
i'm having the same problem:
the main problem is that the resque god recipe doesn't monit the child (forked) process, so you can't have control over the memory or the time they spent.
Here is a solution for observe the child process:
https://github.com/mojombo/god/issues/90
https://github.com/jbgo/god/commit/918bc278e4ca5b8133fe34db06c30ccb93dcb7f0
you can use your own gem forked from the origin to add this files, i preferred to require the new files from the god recipes...
For the time problem you can develop a new condition as the given for it (i'm doing it an will post it here).

Rails / delayed_job - want to load newest version of job class

I'm using the delayed_job plugin in Rails to do background processing, and I'm experiencing a hiccup in the 'agile development' I've been experiencing so far in Rails...
Usually in rails if I hit an error / want to add some new functionality - I just add some code and refresh the page and the new code runs.
With delayed_job, it seems like the job class isn't being reloaded... if a job fails and I go and fix the error and fire the job again, the old code runs again.
Is there any way to make delayed_job load the newest version of the job class before invoking it?
Just in case this has anything to do with it - I know delayed_job has a few different options in the ways to declare jobs / run jobs:
My job class is in the lib directory of Rails and is declared like:
class FooJob < Struct.new(:foo_id)
and I'm invoking the job like this from the controller:
Delayed::Job.enqueue(FooJob.new(params[:id]))
There is nothing builtin to do this. Generally you are responsible for managing and reloading your workers. This is probably just as well since Rails development reloading is good but not perfect, and attempting to auto-reload a delayed job would potentially run into all sort subtle issues that would be pretty opaque to debug inside a worker process. Also, if it automatically reloaded the environment for every job a lot of use cases would get tremendously slow in dev mode.
My suggestion is just to get use to doing rake jobs:work and then Ctrl-C when you make changes. Alternatively you can create a script that just manually runs the jobs on an ad-hoc basis (taken from delayed_job docs):
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'
Delayed::Worker.new.start
I use this hack that seams to work quite nice, but be aware that it's probably very Rails and delayed_job version specific so you probably need to change some things. Tested with Rails 3.2.0 and delayed_job 2.1.4.
Put this into e.g. script/delayed_job_development and run it from the Rails root.
#!/usr/bin/env ruby
require File.expand_path('../config/environment', File.dirname(__FILE__))
require 'delayed/worker'
require "rails/console/app"
class DummyConsoleClass
include Rails::ConsoleMethods
end
dummy_console = DummyConsoleClass.new
worker = Delayed::Worker.new({:quiet => false})
puts "Waiting for jobs..."
loop do
if Delayed::Job.find_available(worker.name).count > 0
puts "Found jobs"
dummy_console.reload!
loop do
break if worker.work_off.sum == 0
end
puts "Done, waiting for jobs..."
end
sleep(2)
end
Please comment if you know that this is a very bad idea or things to be aware of, I mainly use it when editing and testing jobs that run immediately not with jobs scheduled to run long into the future.

Recurring tasks in a Ruby On Rails application: Cron or other?

I am currently writing an application that pulls new information from RSS sources and has to update those RSS sources in a certain frequency. Currently I am pulling only when the user requests a feed but I want to change that behavior to automatic periodic fetching.
I was writing a shellscript that would interact with the database and gets started periodically via cron - but this is lots of double effort so I was wondering what would be the "Rails Way" or "Ruby Way" to do this. I am using Ubuntu, Apache and Passenger. Can you suggest better methods that are maybe even included in the application, so I can easily deploy the app to another machine without having to mingle with cron?
I would suggest doing something like a rake task and using the whenever gem to generate your cron job to run the rake task.
Check out, http://railscasts.com/episodes/164-cron-in-ruby, for more information on the whenver gem.
The main benefit of the whenever gem is that it keeps your application requirements (i.e. the cron job running every x hours, in the application) inside your application, increasing the portability of your application.
I recommend a combination of the two above. You want a rake task, even if you have a direct method already created. This is because server admin stuff that you'd want to run in cron, you might also want to run from the command line occasionally, and this is what rake tasks are good for.
The whenever plugin sounds cool, although I can't vouch for it. Of course, it's good to know how to do things from scratch, then use plugins to make your life easier. Here's the from-scratch way.
Create a new file, lib/tasks/admin.rake
Inside, create the task itself:
namespace :admin
desc "Updates all RSS feeds"
task :rss => :environment do
RssFeed.update_all
end
end
This assumes you have an RssFeed class, and the update_all method does what you'd expect. You can call this from the command line:
rake admin:rss
And you can add this to cron (by calling crontab -l as the web user) and adding this line:
10 0 * * * cd /path/to/rails/app && rake RAILS_ENV=production admin:rss
There are a variety of solutions. For the simplest setup, you can use script/runner in your crontab something like so:
10 0 * * * /home/myuser/myproject/script/runner -e production ModelName.methodname
Methodname must be a static method on your model. You need to reference the project by full path, otherwise it will not be found most likely in the cron environment. Check your crontab man page for info on the crontab syntax if you're not familiar. The above, for example, runs the script at the 10th minute of the 0th hour of every day (at 12:10am, in short).
If you need a more powerful solution, you could use BackgroundRB. BackgroundRB runs a daemon and supports tasks that schedule, and can put results in a database. They even have a simple communication protocol to allow your web processes to request a task be completed, and then have a way to retrieve the result. This allows you to control background jobs right from the web interface, rather than a crontab which just "happens".
There is a good bit more setup needed for BackroundRB to work, but it may be worth it if jobs need to be controlled.
Try using whenever. Eventhough in the end it will create a cron, but the scheduling definition will be written inside your application using Ruby DSL.
For small teams and personal projects, the whenever gem is great. But if your company has an ops team separate from the development team, it might not be ideal.
At my last job, the ops team needed to be able to see the cron we were installing so they could be confident it wouldn't have any side effects for the system. So a DSL solution wasn't going to work. But we (the developers) wanted the cron scripts in version control.
So to compromise, we checked text files with the raw cron, similar to this:
10 0 * * * cd /path/to/rails/app && rake RAILS_ENV=production admin:rss
And we added a step to the capistrano script that installed that to the crontab as part of the deploy.
Try webmin setup in your server. If your hosted site provide it. Go to the below mentioned URL. It's easy to set up and user freiendly.
URL is:
http://your_ip_address:10000/
I have used this in many of my application it's worked for me to schedule cron jobs.

Resources