开发者

Using resque for implementing a command pattern

开发者 https://www.devze.com 2023-02-03 22:33 出处:网络
I am working on a multi-user tree editing app. It uses resque gem f开发者_JAVA技巧or background processes. To avoid runtime multiuser conflicts I want to use command pattern and store user actions in

I am working on a multi-user tree editing app. It uses resque gem f开发者_JAVA技巧or background processes. To avoid runtime multiuser conflicts I want to use command pattern and store user actions in a resque queue so if someone is deleting a branch other user cannot edit children of that branch.

It works, but it is quite slow to pick the job first time from a queue, because resque worker checks for the jobs using 5 seconds interval. It slows down editing interface significantly. It is possibe to do something like this:

    cmd = MyCommand.create!(:attr1 => 'foo', :attr2 => 'bar')
    Resque.enqueue(MyCommand, cmd.id)
    workers = Resque.workers.select {|w| w.queues.include?('my_queue') }
    raise "Should be only one queue for commands!" if workers.size != 1
    not_done = true
    while not_done
      not_done = workers[0].process
    end

It does what I need, but I wonder if there is a more elegant way of doing this. Also, :process is a deprecated method for Worker instances.


I think your design approach is somewhat sound, but Redis/Resque may not be appropriate. What you want is a super fast in-memory queue that's similar to Resque, but that does not come with a polling delay.

I am pretty sure you can use MemCached for this, but there maybe other options. Any solution where your queued commands have to be pulled at certain interval would probably not provide acceptable performance for collaborative editing, unless it's OK to poll maybe every 100ms or even more often.

Finally, if you are placing every action on a single queue which can only process command serially (one at a time), you are inevitably going to end up in a situation where the queue may backup because too many commands are coming in, and they are not processing as fast. This is why a more scalable solution maybe with using versioning, where each element of the tree is versioned, and when updated/changed, all child elements are updated with a new version too. That way, an edit on an older version number is rejected.

Anyway.. good luck, sounds like a non-trivial problem to solve.

0

精彩评论

暂无评论...
验证码 换一张
取 消