Use mongo findandmodify command. Only way I know
On Mar 6, 2013 8:36 AM, "bruce li" <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.