[jira] [Commented] (DIRMINA-845) ProtocolEncoderOutputImpl isn't thread-safe

2011-12-14 Thread Dominic Williams (Commented) (JIRA)

[ 
https://issues.apache.org/jira/browse/DIRMINA-845?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13169893#comment-13169893
 ] 

Dominic Williams commented on DIRMINA-845:
--

Ilya perhaps we can coordinate to create a solution for Red5.

Take a look at related issue regarding how serialization here can lead to 
deadlock http://code.google.com/p/red5/issues/detail?id=164

> ProtocolEncoderOutputImpl isn't thread-safe
> ---
>
> Key: DIRMINA-845
> URL: https://issues.apache.org/jira/browse/DIRMINA-845
> Project: MINA
>  Issue Type: Bug
>  Components: Filter
>Affects Versions: 2.0.4
>Reporter: Ilya Ivanov
>
> ProtocolEncoderOutputImpl uses ConcurrentLinkedQueue and at first look it 
> seems to be thread-safe. But really concurrent execution of flush method 
> isn't thread-safe (and write-mergeAll also).
> E.g. in RTMP several channels multiplexed in single connection. According 
> protocol specification it's possible to write to different channels 
> concurrently. But it doesn't work with MINA.
> I've synchronized channel writing, but it doesn't prevent concurrent run of 
> flushing (in 2.0.4 it's done directly in ProtocolCodecFilter.filterWrite, but 
> ProtocolEncoderOutputImpl.flush has the same problem).
> Here the fragment of flushing code:
> while (!bufferQueue.isEmpty()) {
>   Object encodedMessage = bufferQueue.poll();
> 
>   if (encodedMessage == null) {
> break;
>   }
>   // Flush only when the buffer has remaining.
>   if (!(encodedMessage instanceof IoBuffer) || ((IoBuffer) 
> encodedMessage).hasRemaining()) {
> SocketAddress destination = writeRequest.getDestination();
> WriteRequest encodedWriteRequest = new 
> EncodedWriteRequest(encodedMessage, null, destination); 
> nextFilter.filterWrite(session, encodedWriteRequest);
>   }
> } 
> Suppose original packets sequence is A, B, ...
> Concurrent run of flushing may proceed as following:
> thread-1: Object encodedMessage = bufferQueue.poll(); // gets A packet
> thread-2: Object encodedMessage = bufferQueue.poll(); // gets B packet
> ...
> thread-2: nextFilter.filterWrite(...); // writes B packet
> thread-1: nextFilter.filterWrite(...); // writes A packet
> so, resulting sequence will B, A
> It's quite confusing result especially when documentation doesn't contain any 
> explanation about such behavior.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: [MINA 3] Filter's chain

2011-12-14 Thread Emmanuel Lécharny

On 12/14/11 2:17 PM, Julien Vermillard wrote:

On Tue, Dec 13, 2011 at 5:58 PM, Emmanuel Lecharny  wrote:

Hi,

the current implementation of filter's chain is associating this chain to a
service. In MINA 2, each session had a copy of this chain.

IMO, even if the default chain should be associated to the service, it would
be a better idea to create a copy of this chain for each created session.

the rational behind this choice is that we then be able to add or remove a
filter from the chain dynamically for one specific session. One obvious
usage could be to add a logger when one would want to get some traces for
one session, and not for the whole service. We can also imagine some other
usages.

But it also has another direct advantage : currently, we compute the next
filter to process in the DefaultIoFilterController, where an instance of the
filter chain is stored. This DefaultIoFilterController is associated with a
service, and can then be used by more than one selector, thus by more than
one thread. That means we have to protect the current chain position for a
given selector by storing it into a ThreadLocal. Access to the ThreadLocal
values are way more expensive than accessing a session's current position if
it's a simple integer.

It would be easier if the controller was totally stateless, which would be
possible if the session was holding the filter's chain.  Now, that means we
have to think about the way we should modify a chain for an existing
session. Obviously, if we store the current position in the chain for a
given session, we can't modify this position unless it's not 0, otherwise we
might have some bad errors (ArrayOutOfBoundException, for instance).

I still have to think a bit more about this, but I definitively think that
it's a better approach.

Thoughts ?

Ok let's store de state (current chain position) in the session. that
whould simplify the code (I'm not really happy with the thread local
stuff)

Ok  will do that.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: [MINA 3] Idle session support

2011-12-14 Thread Julien Vermillard
On Wed, Dec 14, 2011 at 2:10 PM, Emmanuel Lecharny  wrote:
> Hi,
>
> we discussed off line with Julien about Idle session support. Here is a sum
> up of what we talked about, and we may have to make some choice.
>
> First of all, it's absolutely mandatory to be able to manage idle sessions,
> in order to kill them, for instance. So we must offer a mechanism by which
> the application developer can handle this.
>
> In MINA 2, if a session is idle for more than a given amount of time
> (configurable), either on read, write or both, then an event is fired on the
> chain, up to the handler.
>
> This is done in the selector loop. The problem with this approach is that
> it's extremely expensive, and most certainly the worst possible solution to
> deal with idle sessions, when it comes to manage hundred or thousands of
> idle sessions. Another issue is that because it's really awfully costly, the
> quantum between two detection is one second. Last, not least, this one
> second os not very precise for a session, as if the session was created
> between two checks, then the delay between the last check and the session
> creation adds up. In other words, we can wait up to one more second to
> detect that a session is idle.
>
> We have some better ideas :
> - first, not all the sessions can be controlled. We need a list of session
> registered for an idle check
> - second, and more important, we must have a dedicated thread
> - last, not least, this mechanism should be optional. Ie, when the session
> is created, it's up to the application to tell that the session must be
> checked for idleness, by registering it into the idleController.
>
> We should also allow a more fine grained control, like 100ms, and even, it
> could be made configurable.
>
> thoughts ?
>

The current mechanism is pretty wrong, and cannot resolve idle time
lesser than 1sec.

We should do something not mandatory and efficient, I'm thinking about
a time-period HashMap of list of session to check (we should update it
for each session I/O events), and a timer checking every X ms the list
of session in the map for this time index.
Well I 'll try to clear my mind a propose a design.

Julien


Re: [MINA 3] Filter's chain

2011-12-14 Thread Julien Vermillard
On Tue, Dec 13, 2011 at 5:58 PM, Emmanuel Lecharny  wrote:
> Hi,
>
> the current implementation of filter's chain is associating this chain to a
> service. In MINA 2, each session had a copy of this chain.
>
> IMO, even if the default chain should be associated to the service, it would
> be a better idea to create a copy of this chain for each created session.
>
> the rational behind this choice is that we then be able to add or remove a
> filter from the chain dynamically for one specific session. One obvious
> usage could be to add a logger when one would want to get some traces for
> one session, and not for the whole service. We can also imagine some other
> usages.
>
> But it also has another direct advantage : currently, we compute the next
> filter to process in the DefaultIoFilterController, where an instance of the
> filter chain is stored. This DefaultIoFilterController is associated with a
> service, and can then be used by more than one selector, thus by more than
> one thread. That means we have to protect the current chain position for a
> given selector by storing it into a ThreadLocal. Access to the ThreadLocal
> values are way more expensive than accessing a session's current position if
> it's a simple integer.
>
> It would be easier if the controller was totally stateless, which would be
> possible if the session was holding the filter's chain.  Now, that means we
> have to think about the way we should modify a chain for an existing
> session. Obviously, if we store the current position in the chain for a
> given session, we can't modify this position unless it's not 0, otherwise we
> might have some bad errors (ArrayOutOfBoundException, for instance).
>
> I still have to think a bit more about this, but I definitively think that
> it's a better approach.
>
> Thoughts ?

Ok let's store de state (current chain position) in the session. that
whould simplify the code (I'm not really happy with the thread local
stuff)


[MINA 3] Idle session support

2011-12-14 Thread Emmanuel Lecharny

Hi,

we discussed off line with Julien about Idle session support. Here is a 
sum up of what we talked about, and we may have to make some choice.


First of all, it's absolutely mandatory to be able to manage idle 
sessions, in order to kill them, for instance. So we must offer a 
mechanism by which the application developer can handle this.


In MINA 2, if a session is idle for more than a given amount of time 
(configurable), either on read, write or both, then an event is fired on 
the chain, up to the handler.


This is done in the selector loop. The problem with this approach is 
that it's extremely expensive, and most certainly the worst possible 
solution to deal with idle sessions, when it comes to manage hundred or 
thousands of idle sessions. Another issue is that because it's really 
awfully costly, the quantum between two detection is one second. Last, 
not least, this one second os not very precise for a session, as if the 
session was created between two checks, then the delay between the last 
check and the session creation adds up. In other words, we can wait up 
to one more second to detect that a session is idle.


We have some better ideas :
- first, not all the sessions can be controlled. We need a list of 
session registered for an idle check

- second, and more important, we must have a dedicated thread
- last, not least, this mechanism should be optional. Ie, when the 
session is created, it's up to the application to tell that the session 
must be checked for idleness, by registering it into the idleController.


We should also allow a more fine grained control, like 100ms, and even, 
it could be made configurable.


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com