You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "David M. Lloyd" <da...@redhat.com> on 2008/02/20 20:43:37 UTC

Sending a message directly upon connect

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.

Thanks.

- DML

Re: Sending a message directly upon connect

Posted by "David M. Lloyd" <da...@redhat.com>.
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

Re: Sending a message directly upon connect

Posted by "David M. Lloyd" <da...@redhat.com>.
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