Ruby on Rails
HowToDoAsynchronousDatabaseUpdates

I want to write an application that needs to be very fast to respond, but can log the transaction to the database at a slower rate. I don’t want to do the database update as part of processing the request, because that will add a lot of latency. In Java, I would either use a separate thread to update the database, or I would use JMS to fire-and-forget the update, which could be handled by a separate process. What facilities does Ruby and/or Rails provide for my needs?

- If you’re using MySQL, you can use INSERT DELAYED which will do-what-you-want.

How can I tell ActiveRecord to do this (MySQL INSERT DELAYED)?

- What about MySQL updates, rather than inserts? I appreciate this info, because I was not aware of INSERT DELAYED, but I’d still like to know about the threading and messaging alternatives offered by Ruby/Rails. Is there any provision in the language for asynchronous execution?

- Using INSERT DELAYED might not be ideal as your process still needs to communicate with database server, which can be a problem (due to latency) if it’s on another physical machine. In that case, you need another thread launched at startup to which you will queue commands “a la Madeleine(fixed mispelling)”. I think that this could be one simple approach:

        # Request does something like this:
        @@cmd_queue << Proc.new { @mything.update }

        # Command Processing thread does something like this:
        while true 
           cmd = @@cmd_queue.shift if ! @@cmd_queue.empty?
           cmd.call
        end

There are locking and notification (wake-ups) issues here and it’s important that the command processor be a thread (as opposed to another process) otherwise there would also be serialization issues also and blocks don’t serialize. I thing though that this is a good start.

- Thank you, Eric. That’s helpful. (BTW, what does “ala madelaine” mean???)


Take a look at the source for send_file send_data :streaming – it seems that it should be possible to send output to the browser, and continue doing your processing. (Not sure what will happen if the user cancels, or the request times out…)

Can anyone confirm this?


Is there anything like JMS or messaging in ruby?
Yes. dRB

a la Madelaine means à la manière de Madelaine – ie the way Madelaine does things


Would there be a way to make use of the “update_attributes” or “update_attribute” in an action method, combined with the “form_remote_tag” functionality to accomplish a record update in real time ala AJAX? Or have I missed the point?


Threads
Don’t be afraid to use Threads in ruby.
However, make sure and add config.active_record.allow_concurrency = true to your environment.rb file.

Also, The config.cache_classes is not compatible with allow_concurrency, so it needs to be turned off, but this should only apply to a development environment. (There is a ticket with a patch for this, but I didn’t try it).