Use mongo findandmodify command. Only way I know On Mar 6, 2013 8:36 AM, "bruce li" <leilmy...@gmail.com> wrote:
> Hello, > I'm working on a piece of code that uses congomongo to access mongodb. > What I want to implement is to use one collection of the DB as a > queue(let's say, it's called "task"). > > Using congomongo, it's easy to fetch a task that is of status :queue : > (def t (fetch-one :task :where {:status :queue})), > and also it's simple to update it: (update! :task t (assoc t :status > :running)) > > But how to make a safe and consistent "dequeue" operation in concurrent > context? A naive dequeue should look like this: > > (let [t (fetch-one:task :where {:status :queue})] > (update! :task t (assoc t :status :running)) > t) > > But taking concurrency into consideration, this implementation is > error-prone, at least from my point of view. Consider this: > > When 2 threads are fetching the task, it's very likely that the task is > fetched twice using the previous piece of code and they would be executed > twice. > > Do we have something like transaction? Something that will enforce the > "fetch-one" and "update!" statement are both executed before another > “fetch-one" operation is adopted? > > What I can think of is to use an agent. And my code looks like this: > > (def db-agent (agent nil)) > (defn dequeue [] > (letfn [(do-dequeue [da] > (let [task (mongo/fetch-one :task :where {:status :queue})] > (when task > (mongo/update! :task feed (assoc task :status :running))) > task))] > (send db-agent do-dequeue) > @db-agent))) > > However, I still doubt the correctness of this solution. Right before the > @db-agent is called, won't another thread call "dequeue", which will > involve another "send” and change the value of db-agent? > > I'm wondering if anyone can help. Thanks. > > > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.