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