James Smith wrote:
This is my current sequence of actions:
- I have a link_to in a rhtml file that when clicked on calls a method in my controller
- This method runs through a loop
- At some points in this loop i would like to be able to stop and update something in my rhtml file (and hence the webpage), and then continue back on with the loop
- is this possible?
This is the fundamental problem with responsive GUIs - you can't just go into a loop from an event handler.
(Note that everything from the Model down thru the database is just one huge system to keep the GUI responsive without looping over updating data and such...)
If I had this problem with a desktop GUI (such as a Win32 window), I would start a window timer, and then "time slice" the loop. I would store its looping index in a window variable, and at each timer tick I would update the index, run one tick of the looped activity, and then optionally update the screen.
Desktops prefer that system (it's often a better design than threading), and they allow window timers with 0 duration, to execute each time the CPU is idle. The result is perfectly responsive, and you obviously can't do it.
The new pattern here is to use periodically_call_remote, and then do a small batch of items. Maybe loop until you find a reason to update the screen. Then return an update, store your looping index, and await the next event. But you can't set periodically_call_remote to less than a second, because it slowly beats the crap out of every layer in your system, from the browser to the server.
The next more sadistic technique would be to start a timer (or possibly even - shudder - a thread) in the server. It will loop thru items, and push window updates as objects into a database queue. Then you use periodically_call_remote, with an easier frequency, to pop that queue and update the browser. Note that storing the queue in the database takes care of all the ACID concurrency the queue needs, and starting a new thread might be safe. Only do that as a last resort - look for a timer system so Rails can send its unused CPU cycles to your background task.