Rails how to simulate background processing - ruby-on-rails

I am creating a simulator in rails for an upcoming product. We want to model how a device that transmits data will behave, so I need to simulate the creation of multiple objects at different times. Basically, I want a method that does this:
def simulate_scenario_a
create_data_packet_a (instantly)
create_data_packet_b (5 mins delay)
create_data_packet_c (10 mins)
end
These all need to be sent to the front end api as soon as they are created but i am not sure of a suitable method to use to delay them. All my delays so far prevent the main method simulate_scenario_a from completing so they are all fired at the same time. Should i use delayed jobs gem?? Advice needed

Consider one of background jobs gem. I prefer sidekiq gem.
Using sidekiq's API, you can
def simulate_scenario_a
DataPacket.create!(params)
DataPacket.delay_for(5.minutes).create!(params)
DataPacket.delay_for(10.minutes).create!(params)
end

Related

Rails Controller - Return and then perform complex action (without worker)

I want to create an API endpoint in my app that takes data and performs a complex, time-consuming operation with it, but only after returning that the data has been received.
As in, I'd love to be able to do something like this:
def action
render json: { data_received: params[:whatever].present? }
perform_calculations( params[:whatever] )
end
Unfortunately, as I understand it, Ruby/Rails is synchronous, and requires that a controller action end in a render/redirect/head statement of some sort.
Ordinarily, I'd think of accomplishing this with a background worker, like so:
def action
DelayedJobActionPerformer.perform_later(params[:whatever])
render { data_received: params[:whatever].present? }
end
But a worker costs (on Heroku) a fair amount of monthly money for a beginning app like this, and I'm looking for alternatives. Is there any alternative to background workers you can think of to return from the action and then perform the behavior?
I'm thinking of maybe creating a separate Node app or something that can start an action and then respond, but that's feeling ridiculous. I guess the architecture in my mind would involve a main Rails app which performs most of the behavior, and a lightweight Node app that acts as the API endpoint, which can receive a request, respond that it's been received, and then send on the data to be performed by that first Rails app, or another. But it feels excessive, and also like just kicking the problem down the road.
At any rate, whether or not I end up having to buy a worker or few, I'd love to know if this sort of thing is feasible, and whether using an external API as a quasi-worker makes sense (particularly given the general movement towards breaking up application concerns).
Not really...
Well you can spawn a new thread:
thread = Thread.new { perform_calculations( params[:whatever] ) }
And not call thread.join, but that is highly unreliable, because that thread will be killed if the main thread terminates.
I don't know how things with cron jobs are in Heroku, but another option is to have a table with pending jobs where you save params[:whatever] and have a rake task that is triggered with cron periodically to check and perform any pending tasks. This solution is a (really) basic worker implementation.
Heard about sucker_punch, you can give it a try. This will run in single webprocess but the downside is that if the web processes is restarted and there are jobs that haven't yet been processed, they will be lost. So not recommended for critical background tasks.

Is it possible to string / queue Ruby actions?

I've written a number of actions in a RoR app, that perform different actions within process.
E.g.
- One action communicates with a third party service using their API and collects data.
- Another processes this data and places it into a relevant database.
- Another takes this new data and formats it in a specific way.
etc..
I would like to fire off the process at timed intervals, eg. Each hour. But I don't want to do the whole thing each time.
Sometimes I may just want to do the first two actions. At other times, I might want to do each part of the process.
So have one action run, and then when it's finished call another action. ETC..
The actions could take up to an hour to complete, if not longer, so I need a solution that won't timeout.
What would be the best way to achieve this?
You have quite a few options for processing jobs in the background:
Sidekiq: http://mperham.github.io/sidekiq/
Queue Classic: https://github.com/ryandotsmith/queue_classic
Delayed Job: https://github.com/collectiveidea/delayed_job
Resque: https://github.com/resque/resque
Just read through and pick the one that seems to fit your criteria the best.
EDIT
As you clarified, you want regularly scheduled tasks. Clockwork is a great gem for that (and generally a better option than cron):
https://github.com/tomykaira/clockwork

What language/technique should I use to add a game loop to a Ruby on Rails based webgame?

I'm building a web game in Ruby on Rails that relies on a choose-your-own-adventure mechanic coupled with a time-waiting system (a la Zynga and the come back in 15m, 30m, 1hr, etc concept).
However, I need a game loop to run in the background to constantly run and check if the "quests" that players are waiting on are ready and if so, ping the user(email/smartphone push notification/whatever they want). I obviously need it to do more than just this, but this is the core functionality.
I don't want to throw this into a Rails controller because I don't need the game logic running on every single page view or for it to be hammered when tons of users are on, rather I just need a loop to run continuously (at a set interval) and handle all of the small tasks that will be necessary to run the backend of a multiplayer game.
What language/technique is best for this, or do I even need to leave my Ruby/Rails foundation at all?
EDIT: This game does not feature a "persistent" world and has no real need of persistent connections with clients. The game is spread out over many pages and it will feature some asynchronous functionality (a news 'ticker' at the top that has updates pushed to it, etc).
Sounds like you're looking for a background worker of some sort. Heroku supports a scheduler that you can set to run every ten minutes; documentation is here: http://devcenter.heroku.com/articles/scheduler?preview=1
Otherwise, a system like Resque ( https://github.com/defunkt/resque ) or DelayedJob ( https://github.com/tobi/delayed_job ) would be good plugins for handling periodic introspection without tying up your controllers.
Check out either PusherApp or PrivatePub
My idea is that the player will conduct a movement, and then broadcast out (via pusher or private pub) to the other players that it is their turn.
Check on page load or by JS request if the event is finished already. In example when you show page that inform your user about time to end process then you will update it with JA, when time come to 0.0s then refresh page or use AJAX and show info that process is finished. If user leave the page and return back you will know that he finished that process.

Rails async jobs (fast view and minimal delay)

Hi I have developed a rails app.
When one controller receives a request, it will render a client view AND send another action to a LED ticker display via TCP/IP. BUT send stuff to LED ticker display takes about 3 second. And I might have 5-10 LED ticker to send.
This will block client view rendering. (I can use multi-thread to send to each LED ticker display, but still have to delay 3-5 seconds when thread queue joins)
Question:
Since client view has nothing to do regardlessly if sending to LED fails.
Can I make it an async job?HOW?
Should I make a Sinatra background process listens stuff and send to LED by the sinatra app?
Thanks!
The spawn-plugin from https://github.com/tra/spawn should do nicely and can use forking (by default), threads or yields.
I use spawn with fork for long-running, fairly heavy tasks and it works like a charm. A simple example would be :
spawn(:method => :fork) do
do_led_stuff()
end
and since you don't require any feedback from the LED-ticker you won't have to wait() for the spawned process either.
Have you tried delayed_job (http://rubygems.org/gems/delayed_job)? I don't know if it's compatible with Sinatra, but maybe you can have a look at it.
You can use Resque (https://github.com/defunkt/resque)

Timed server events with ruby on rails

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.

Resources