After further analysis, I don't think this is globally a good
strategy.

I looked into a solution with a "(ref (clojure.lang.PersistentQueue/
EMPTY))" in the selector agent.  The plan was to have be able to queue
"updates" to the schedule synchronously.  Half-way through the
implementation, I realized this is equivalent to by-passing the entire
agent system and still wouldn't work anyways.

Even *if* send/send-off were forced to queue synchronously, the wakeup
strategy isn't guaranteed to work.  There is still the possibility
that "Selector.wakeup()" will be executed after the "dispatch" action
has started, but before it calls "Selector.select()".  What would be
necessary is for the agent system to sort-of interrupt calls to
"dispatch" as soon as something else is sent to the agent.  Apart from
requiring the most insane hack ever, this solution would be nothing
close to elegant.

Basically, I can't block on "Selector.select()", so I have to poll.
Can't wait for JSR203 (http://www.jcp.org/en/jsr/detail?id=203) to be
approved as part of Java 7.  Maybe that API will be less of a
hassle...

By the way, this is all for an open source project.  I've got the
basic parts working, but it's still under heavy architectural
changes.  As soon as version "0.1" is decent, I'll push the repository
to GitHub and notify you guys.


Regards,

André Caron

On Apr 14, 5:58 pm, André Caron <andre.l.ca...@gmail.com> wrote:
> 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