mardi 29 décembre 2015

Rails and sucker_punch: Wait for high frequency updates to complete before running background job on that model

In my Rails 3.2 project, I am using SuckerPunch to run a expensive background task when a model is created/updated.

Users can do different types of interactions on this model. Most of the times these updates are pretty well spaced out, however for some other actions like re-ordering, bulk-updates etc, those POST requests can come in very frequently, and that's when it overwhelms the server.

My question is, what would be the most elegant/smart strategy to start the background job when first update happens, but wait for say 10 seconds to make sure no more updates are coming in to that Model (Table, not a row) and then execute the job. So effectively throttling without queuing.

My sucker_punch worker looks something like this:

class StaticMapWorker
    include SuckerPunch::Job
    workers 10

    def perform(map,markers)
        #perform some expensive job
    end
end

It gets called from Marker and 'Map' model and sometimes from controllers (for update_all cases)like so:

after_save :generate_static_map_html

def generate_static_map_html
    StaticMapWorker.new.async.perform(self.map, self.map.markers)
end

So, a pretty standard setup for running background job. How do I make the job wait or not schedule until there are no updates for x seconds on my Model (or Table)

If it helps, Map has_many Markers so triggering the job with logic that when any marker associations of a map update would be alright too.

Aucun commentaire:

Enregistrer un commentaire