Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 431
user573335 Avatar asked Jan 12 '11 21:01

user573335


2 Answers

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.

like image 115
zaius Avatar answered Sep 29 '22 22:09

zaius


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

like image 27
Chris Kimpton Avatar answered Sep 29 '22 20:09

Chris Kimpton