Rails - loading page Parallel - ruby-on-rails

The idea is to have a page with a parallel process and in the same time show a loading .gif or a JS game because the waiting is soo long, like this:
So, that's basically the idea, enter a controller that lauch a parallel process that's takes a lot of time meanwhile display his page that have something to
entertain the user and, by ajax, is constantly checking if the parallel process is done, so display a button to continue to the next page
Consider that is done this way because the process itself takes over 10 minutes of time so the timeout of the server kills the process before it's complete so in this idea the timeout is completed when is display the wait.html.erb and in the same time the parallel process is still alive
Also consider that i don't do anything yet because i don't know if the very idea is possible, so my question is if its possible? and how will be done?

You could simply use background processing worker (Sidekiq in this example):
class HardWorker
include Sidekiq::Worker
def perform(user_id)
VeryLongProcess.run
notify(user_id)
end
end
And the notify method could either push notification to user (using Websockets for example) or just store a setting in Redis or other DB that the job has completed. This in turn could be read by your AJAX call.

Related

How to monitor a long process in a JSF 2/Primefaces/JBoss application

I have a JSF 2/Primefaces/JBoss application that has to run some long term processes from time to time. Specification says that once the process is started, its progress has to be monitored, showing the occurrence of intermediary phases of it.
The total count of steps is retrieved in the beginning and a progress bar has to show the process evolution and and estimate of the remaining time, based on the statistics calculated during the process execution. It's not like only showing that something is happening, but actually showing how much the process still remains to be done.
Even if the user closes the page, the process has to continue and if the user gets back to the page, it has to show the current progress status of the process. If the process is already finished, then some informations should be presented, like the number of objects processed and, the total time taken and some other statistics, like the object that took longer to be processed.
How to accomplish that in a JSF 2/Primefaces/JBoss application?
You question can be broken down into two main problems.
1. How to log and track the status of a job.
2. How to present this information in the UI.
Depending on your requirements and your JBoss version, you may want to consider using a managed thread. You must decide how you will track the process steps. You could log each completed step in a database or keep it in memory. How will errors be handled? What if the process does not complete? Once you have these back end design decisions completed and implemented you just need to figure out what you want the UI to be like.
As mentioned in the comments section, primefaces offers a couple different options such as polling or server sent events. If you are using polling leaving the page and revisiting should already be handled by presenting the result for any point in time. You would then just need to refresh the view on an interval.

Periodically updating the game state for all users

I'm working on writing a poker room game in ruby. I'd like to set a time limit on how long each player has to decide what their play is, at the end of which period the game will decide what happens next. (did this particular player time out? did everyone fold? is this the end of the game? etc)
I'd like to poll what's happening on the server from the user's side with JS, but how do I make the server run a background task that advances the state of the game every N minutes? (a value that could be different per each poker room)
This is quite a hard problem to solve. Here might be one of the easiest ways to solve it. Using a background scheduling. For example with sidekiq.
You can schedule a job to update the game state like:
class GameTimoutTrigger
include Sidekiq::Worker
def perform(game_id)
game = Game.find(game_id)
game.timeout!
end
end
And when a game round starts you schedule the timeout trigger
round_timeout = game.round_interval
GameTimoutTrigger.perform_in(round_timeout, game.id)
Be aware that sidekiq will poll jobs in the schedule on intervals (15 secs by default). So there will be always some delay on the timeout.
If the round time must be always exactly 60 seconds for example, you could save the round start and stop timestamps, and user's action timestamp. And only accept user action if it's between the round range. But this might be not necessary. It's just a heads up.
You got the right idea with setInterval().
window.setInterval("javascript function",milliseconds);
The "javascript function" can update the game on the client side and make a request to the server to update. Make sure to clearInterval() if you want to prevent the function from running.
If you're really looking for a way to make the server run a background task, you can maybe try the delayed-jobs gem, but websockets or setInterval is probably a better way to go.

Send feedback to the user for a long running operation in Grails?

I have a long running operation in my Grails application. My first solution is simply to perform the operation in the controller and let the user wait until the action is finished. This is not an acceptable solution, I want to show the user the progress of the action. The progress is simply text. The action can take from 10 seconds to roughly 30 minutes.
How can I show the progress to the user for my long running action?
First you might want to try the Executor plugin so you can run the job in the background. This works quite well.
Then I guess you have 2 options. Have the browser poll the server via Ajax for an update (as Tim pointed out the JProgress plugin would do something like this for you) or get even more bleeding edge and consider HTML5 WebWorkers for a kind of server push approach. WebWorkers are not available in
You will need something like a Task or Job domain class with a field percentageComplete. The controller will create and save the Task or Job and then spawn a new thread to execute it. Perhaps place the execution code in a service.
It will be up to your execution code to update the Task or Job's percentageComplete field as it completes its task. Then you can poll the job (via ajax) to see how the job is progressing.
Note: determining that percentage which is complete is very much to up to your specific code. You will probably have to just come up with a best guess based on the knowledge you have. Even for an operation where it is obvious how to determine percentage complete (like a file download), it is not certain (network issues, etc.)
Can you determin the state of your progress? Let's say in percent?
I would create the long operation as a quarz job (background) and query the state of job/ long running progress via ajax.
The JProgress plugin might help, but I've never tried it out...

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)

Ruby/Rails synchronous job manager

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

Resources