I've been doing some research but I can't figure out on how to do this in Rails.
I need to execute some code after a certain amount of time. I found some gems that can handle this but I don't want to use any.
I basically have a create function in a Rails controller and some stuff need to happen there after 24 hours.
EDIT: I tried with sleep but it needs to be async and sleep will stop everything from running until it's done, even if it is in a if statement.
You need to create an ActionJob with rails generate job your_job_name.
Then you can delay its execution
YourJob.set(wait_until: 1.day.from_now)
For this to work you indeed need a Job queue to be configured for your project. I personally recommend Sidekiq
Sadly, you will have a hard time avoiding setting up a gem for this.
Related
I use rake tasks in my rails application, it's fine when dealing with "small amount of data" but if several scores of thousand of record needs to be retrieved / computed the tasks can take a lot of time.
Rake tasks are very easy to understand and develop and I'd really like to keep using them but is there some recommendations when it comes to huge amount of data ?
I was thinking of map/reduce algorithme for instance. Is that the way to go ?
It's not rake that's slow. Rake is just firing up an instance of your application and running whatever you sent to it.
You can try to re-factor your code and see if there are some shortcuts that you didn't see before.
You can try to thread or fork tasks off if it is stuff that can be done simultaneously.
I would recommend using Spawn if you are going to attempt this in your rails app.
Sometimes your jobs just need to take a long time. Big Data = Big Time.
Also, if you are running your rake tasks regularly throughout the day I would recommend using using something like Delayed_Job to handle this instead so you aren't firing up and quitting rails instances each time you need to run a task.
I recommend threach and jruby.
I want to make a game in rails (not with flash, just html). Every action should take some time to execute. For example, user can send an action to his hero "go learn ". It should lasts for 10 minutes. What's the best way to implement it?
I want to store player tasks in my database, but how should I do their execution?
1 way: when user log in or do something, check his tasks and look for finished ones.
2 way: check tasks on my app every X seconds and look for finished ones.
3 way: use something like Delayed Job gem. Do you think its good for my problem?
You could use delayed job, to run the task.With that there is problem that you will have tomanage "many" workers when there is extra load on the site, but its not that bad either, its doable as long as it "runs" every task exactly after 10 minutes.
You can still use a combined approach using 1 & 2 which would generally work.
I am now researching for a solution to perform similar task and just recently came across a railscasts episode that I found worthy of noting down.
Using custom deamons (and a number of other interesting topics) found here.
P.S.
I see that you have asked this question a while back. Could you please share how you ended up implementing your solution.
Cheers
hi
i'm going to set up a rails-website where, after some initial user input, some heavy calculations are done (via c-extension to ruby, will use multithreading). as these calculations are going to consume almost all cpu-time (memory too), there should never be more than one calculation running at a time. also i can't use (asynchronous) background jobs (like with delayed job) as rails has to show the results of that calculation and the site should work without javascript.
so i suppose i need a separate process where all rails instances have to queue their calculation requests und wait for the answer (maybe an error message if the queue is full), kind of a synchronous job manager.
does anyone know if there is a gem/plugin with such functionality?
(nanite seemed pretty cool to me, but seems to be only asynchronous, so the rails instances would not know when the calculation is finished. is that correct?)
another idea is to write my own using distributed ruby (drb), but why invent the wheel again if it already exists?
any help would be appreciated!
EDIT:
because of the tips of zaius i think i will be able to do this asynchronously, so i'm going to try resque.
Ruby has mutexes / semaphores.
http://www.ruby-doc.org/core/classes/Mutex.html
You can use a semaphore to make sure only one resource intensive process is happening at the same time.
http://en.wikipedia.org/wiki/Mutex
http://en.wikipedia.org/wiki/Semaphore_(programming)
However, the idea of blocking a front end process while other tasks finish doesn't seem right to me. If I was doing this, I would use a background worker, and then use a page (or an iframe) with the refresh meta tag to continuously check on the progress.
http://en.wikipedia.org/wiki/Meta_refresh
That way, you can use the same code for both javascript enabled and disabled clients. And your web app threads aren't blocking.
If you have a separate process, then you have a background job... so either you can have it or you can't...
What I have done is have the website write the request params to a database. Then a separate process looks for pending requests in the database - using the daemons gem. It does the work and writes the results back to the database.
The website then polls the database until the results are ready and then displays them.
Although I use javascript to make it do the polling.
If you really cant use javascript, then it seems you need to either do the work in the web request thread or make that thread wait for the background thread to finish.
To make the web request thread wait, just do a loop in it, checking the database until the reply is saved back into it. Once its there, you can then complete the thread.
HTH, chris
I'm using a Observer on my classes. When one of the records is created/updated I need to notfify another service (via a URL call). What is the best way to do this to avoid slowing down my class? Would using a gem liked delayed_job be overkill?
In my Observer's after_update() / after_create() I just want to launch a thread that calls the URL...
If your notifier is non-thread blocking, you could simply spawn a thread and perform the notification there. That way, your program will continue to run while that thread is waiting on the response.
Of course, you'll want some way to handle failure. You could have it try three times, and if it still fails, write a notification to the log or something.
The best (most reliable) solution would be to use a job queue. That way, if a job fails outright, you can inspect and resubmit the job again.
Definitely use a community supported/accepted gem like delayed_job or resque. It's really not as hard as you think and your app will scale better down the line.
I am attempting to create a web-based game in Ruby on Rails. I have a model named 'Game', which has a datetime in the database entry that corresponds to a time that I would like the server to call the Game model's update_game function. Depending on the game's settings, this could be every 30 seconds to every 12 hours.
Ruby on Rails only seems to work when it receives an HTTP request; is there a slick way to get my game to update on a periodic basis independent of HTTP requests?
I'd look into delayed_job for this. When the game starts, you can create a delayed_job for the first update, and every run after that can add a new job at the correct interval until it's done.
I'd do lots of testing though ;) - you don't want to let the jobs get away from you.
Rails itself doesn't do this; cron does this. Ruby does, however, have a gem named Whenever to make easier the declaration and deployment of new cron jobs.
However, if you are really going to expect a large amount of games to reliably update every 30 seconds, you may want to take a different approach if updating a game would take any significant amount of time. Perhaps once the game is accessed, the game could run the update as many times as necessary (e.g. if 3 minutes had passed and the interval is 30 seconds, run 6 updates once requested). This may or may not be a good option for your setup, however, so figure out which method is more viable for your purposes.
Look into background processing options and possibly cron.
I like the gem 'rufus-scheduler' which works within Rails, though I'm not sure you can programmatically add more tasks to it.