I've posted this question on StackOverflow[1], but it might be a bit
technical, so I'll ask it on the mailing list where I might get more
precise expertise on Clojure.

[1]: http://stackoverflow.com/questions/5669084/clojures-send-is-asynchronous

I'm writing a simple networking framework for Clojure using Java's
"New I/O" package. It manages a pool of "selector agents", each of
which holds a `java.nio.channels.Selector`.

I defined a `dispatch` action to for the selector agent. This action
blocks on a call to `Selector.select()`. When that returns, the
selector agent iterates over the selected keys and performs I/O. When
I/O is completed, the selector agent send's itself the dispatch action
using `send-off`, effectively looping on calls to `Selector.select()`.

When I want to add a new channel or change a channel's interest ops, I
send the selector agent the appropriate action and then unblock the
selector (it's blocked on `Selector.select()`). This ensures that
`(send-off selector-agent dispatch)` in the selector agent is executed
after `(send selector-agent add-channel channel)` in whatever agent
changed the `SelectionKey.inrestOps()`.

I thought this would be bullet-proof since the call to `send-off` is
performed before the selector waking up, and thus, before the selector
agent send itself the `dispatch` action.  However, this yields
inconsistent behavior.  Sometimes, the `dispatch` action occurs first
and sometimes it doesn't.  My understanding is that `send` and `send-
off` are themselves asynchronous in that they return before the agent
action being sent is actually queued in the agent's action backlog.

Is this correct?

This is normally not an issue; the action dispatch from different
agents/threads to the same agent is usually unpredictable and a non-
issue.  In this case, the real culprit is that I need to block on
`Selector.select()`.  One obvious workaround is to put a timeout on
the sleep operation, so that I don't need to manually unblock the
selector.  This puts me in the classic polling lose/lose situation,
where I need to decide on the polling frequency: too few polls and
suffer latency, too many polls and slow down the whole machinery.

Does anyone have any better ideas, or can `send`/`send-off` be made to
actually queue the actions synchronously such that they are executed
int the *exact* order they are sent?

Thanks,

André Caron

-- 
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