I'm not an expert on asynchronicity with clojure, but I'll benefit from the
fact i'll be the first to answer :-)
But please take this with a grain of salt.

As I see agents, in their generality, they are "a generic way to handle a
state asynchronously (commands from multiple non organized sources - and
they don't need to be organized-)".

Maybe you could indeed consider your agent is responsible for the "state" of
the polling thread : active, sleeping, and when active the polling strategy.
One thing to keep in mind is that no "order" sent to the agent will be lost,
they will apply in order, one-at-a-time.

So I don't think you need this message-queue at all (or maybe I haven't
understood what it is or I'm mislead by its name), send directly your order
to the agent as what you want to change in its state.

(If I'm right, it may well be even better than you imagined :-) )

HTH,

-- 
Laurent

2009/10/8 Garth Sheldon-Coulson <g...@mit.edu>

> Hi All,
>
> This is a question about whether I can use agents or some other Clojure
> concurrency feature to manage a multithreaded process elegantly and
> extensibly. The following is a thought I had for how to do it, but I would
> appreciate additional suggestions.
>
> I have an application that needs to poll an outside service at regular
> intervals---every 50ms or so. For various reasons the polling takes place in
> a separate thread. I need to be able to send messages to the separate thread
> (call it the "polling thread") from the other threads in the application.
> For instance, I need to be able to tell it to go to sleep (stop polling) and
> wake up (restart polling), and I need to be able to give it new instructions
> on how to process items it reads from the outside service.
>
> Currently, I send messages to the thread by conjing them to a ref that the
> thread knows about, specifically a ref that the Thread's run function is
> closed over. I then send the thread an interrupt, which lets it know to look
> in the ref to see if there's anything new and interesting to do.
>
> In practice, this means sending messages to the thread goes something like:
>
> (dosync (commute message-queue conj message-item))
> (.interrupt polling-thread)
>
> There's nothing wrong with this, but I'd like to know if I could use agents
> instead. I want to be able to abstract away from the interrupt, even if the
> abstraction uses an interrupt internally.
>
> Could I create an agent containing the thread object?
>
> (def poll-agent (agent (Thread. f)))
>
> And send it messages like this:
>
> (swap! message-queue add-item item)
> (send poll-agent check-queue)
>
> Where check-queue is :
>
> (defn check-queue [t] (io! (.interrupt t)))
>
> Are side-effects such as an interrupt permissible in functions sent to
> agents? That the io! doesn't throw an error indicates yes, but please
> correct me if I'm wrong.
>
> Is wrapping a thread object in an agent a reasonable thing to do?
>
> Are there better ways to handle this situation? Is there any way the queue
> could be added to, and the thread interrupted, in a single call? I don't
> think I can include both the queue and the thread in a single agent and send
> the queue conj and the interrupt in a single send call, because I need to be
> guaranteed that the conj takes place before the interrupt...
>
> But ideally I'd like something like:
>
> (send poll-agent add-item item)
>
> that would take care of both interrupting the thread (potentially waking it
> up) and putting the item somewhere it could find it.
>
> 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to