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.


Reply via email to