I opened a bug for this: https://issues.apache.org/jira/browse/DIRMINA-535
- DML
On 02/20/2008 03:14 PM, David M. Lloyd wrote:
On 02/20/2008 01:43 PM, David M. Lloyd wrote:
In the protocol I'm working on, the client and server each need to
send a message immediately upon connection. If I send the message in
my IoHandler.sessionOpened() method, is it safe to say that the
message will be sent before the first IoHandler.messageReceived()
occurs? If so, that fact should be in the javadoc for IoHandler.
An interesting IRC conversation ensued from this question. Here's the
transcript from #mina on irc.freenode.net (slightly edited to remove
unrelated comments):
Cast of characters:
dmlloyd = Me (David M. Lloyd)
tazle = Tuure Laurinolli
mike_heath = Mike Heath
<dmlloyd> hm, even with the IoSessionInitializer there's no way to
guarantee that I can write a message before a message is received
<dmlloyd> it's almost as if there should be a lifecycle for an ioSession
<dmlloyd> created, connected, started
<dmlloyd> created = the session is created but not yet connected (e.g.
in IoSessionInitializer)
<dmlloyd> connected = the session is connected but not added to the
selector/whatever (so the IoHandler is guaranteed not to be invoked yet,
but you can still send)
<mike_heath> IIRC, you can use an the executor service filter and it
will ensure the correct order of events.
<dmlloyd> started = IoHandler receives messages
<mike_heath> The problem is that the connector thread and IoProcessor
threads are different.
<dmlloyd> once the connection is up, sure
<mike_heath> Even before the connection is up, the executor filter will
order the events.
<dmlloyd> yeah but the "starting" event always has to be a read for that
to work
<dmlloyd> e.g. reads will occur in order
<mike_heath> Aaahhh.
<dmlloyd> but you can't insert a write to happen *before* the reads start
<dmlloyd> hm, is sessionOpened() guaranteed to be called before any
messages are received?
<dmlloyd> the docs are unclear
<mike_heath> IMO sessionCreated and sessionOpened should be called
before any message have been received.
<mike_heath> Perhaps we should discuss this on the ML.
<dmlloyd> maybe. I'll look over the source first.
<tazle> dmlloyd: how does "write before any reads" make sense?
<dmlloyd> how does it not?
<dmlloyd> usually a protocol handler sends data in response to receiving
data
<tazle> dmlloyd: can't you send in sessionOpened()?
<dmlloyd> in this protocol, the server and client both send an initial
message upon connect
<dmlloyd> on the client side I need to send the initial message before
the server's initial message is received
<dmlloyd> to prevent a different message from being sent before the
initial message
<dmlloyd> I can, but I can't tell if sessionOpened() is guaranteed to
run and complete before any incoming messages are processed
<dmlloyd> I hope it is
<dmlloyd> it's hard to follow what's happening in the MINA codebase though
<tazle> dmlloyd: shouldn't it be enough that sessionOpened() is called
on IoHandler before messageReceived()?
<dmlloyd> yes, that would be sufficient - however there is nothing in
the docs that says that is true
<tazle> dmlloyd: hmm, true
<dmlloyd> I would hope that is the case, otherwise sessionOpened() is
not very useful
<tazle> I guess NioSocketConnector is the most relevant implementation here
<dmlloyd> yeah, that's what I'm using for now
<dmlloyd> though I may try out APR at some future point
<dmlloyd> heh, seriously, I can't find where sessionOpened is called
<mike_heath> DefaultIoFilterChain:677
<dmlloyd> well, yeah
<dmlloyd> but when is the filter chain invoked?
<tazle> hmm
<tazle> tracing the call chain from connect() only gets me to
fireSessionCreated(), which is fired in the same method as the session
is added to its selector
<dmlloyd> where is that?
<tazle> AbstractPollingIoProcessor.java:267 in my (somewhat dated) checkout
<tazle> init(session) earlier registers the underlying SocketChannel to
the Selector of NioProcessor
<dmlloyd> crap
<dmlloyd> well that's no good
<dmlloyd> hm, that's arguably a bug
<dmlloyd> there's no filter chain yet
<dmlloyd> what if a message comes in? it would skip the whole filter chain
<dmlloyd> unless that's guaranteed to be the same thread?
<tazle> dmlloyd: I think there's only one Worker
<tazle> also, fireSessionOpened() may be called from three places, one
of which seems to be vmpipe-specific
* dmlloyd headache
<dmlloyd> this shouldn't be this complicated :)
<tazle> I think it has to be, if the transprot implementations are
supposed to be this pluggable
<tazle> hm, an IoServiceListener fires both sessionCreated() and
sessionOpened() rigth after each other
<tazle> err, IoServiceListenerSupport
<tazle> oh, and I guess it all depends on what is registered in the
NioSocketConnector as IoServiceListener
<tazle> oh wait, the getListeners on line 267 always returns
IoServiceListenerSupport, which fires both sessionCreated and
sessionOpened on the session
<tazle> dmlloyd: right, so apparently both sessionCreated and
sessionOpened are actually fired right after one another from the same
method, it seems
<tazle> which makes is puzzling as to why both exist
<dmlloyd> baffling
<tazle> dmlloyd: will you post something to the ML?
<dmlloyd> I did already
<tazle> ok
<dmlloyd> I think I'll reply to it with this whole conversation :)
- DML