RestComm/jdiameter

Threading model of session objects

Opened this issue · 1 comments

Hi,
I came across kind of a unexpected locking behavior of jdiameter's session objects which lead to deadlock with the assistance of my code. This in my opinion should not happen and there is no need for current implementation. But I might be wrong and there is good reason for how things are done.

Background

Let me start with a bit of a background. I am currently working on purpose specific network traffic generator. This generator is intended to be used against LTE's PCRF server and as such I need to somehow define what requests and answers should be sent and should be received. The way how this is done is through concept of scenarios, simply put scenario is sequence of description of requests and answers which are processed in order. One instance of scenario represents one active device in LTE network.

To be able to simulate real network traffic I need to run a lot of scenario instances at once and most importantly be able to dynamically change number of these active scenarios. To do this there is need for synchronization in my Client class which handles sending and receiving messages (it is registered as a listener for Gx and Rx interface). So I have one lock which is locked during sending and receiving message which is the starting point of problems I experienced.

Problem

I am not saying my architecture is ideal it definitely might be improved. But it was kind of a surprise that jdiameter has the same threading/locking model like my code.

As I stated before I came across deadlock which was caused by my and jdiameter's code. The problem was when I was releasing Gx sessions while lowering number of active scenarios. Lowering of scenarios is done in the middle of scenario, it is possible and highly probable that while releasing session there will be some incoming requests/answers. And that is where the problem arose.

While I was trying to release Gx session, I was obviously locked in my code in my Client class and releasing session would try to lock Gx session lock, but that was locked because another message arrived in the same exact moment. While message arrived it tried to call my registered listener which is my Client class, but receiving of message in my code is also handled with synchronization, so the lock was already locked on releasing session. Thus... deadlock.

Just for reference ... releasing is here in Gx session: https://github.com/RestComm/jdiameter/blob/master/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/ClientGxSessionImpl.java#L655 ... and receiving is handled here if I am not mistaken: https://github.com/RestComm/jdiameter/blob/master/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/ClientGxSessionImpl.java#L260

Solution?

In my opinion, jdiameter as a library should not hold lock while handing control over to users defined callback. In the situation like mine it is not expected and as far as I know not documented. I do not see any reason why the lock should stay locked, the state of session should be idle and is not somehow temporary or in processing, but as I said there might be reason why the implementation is as stated.

I know that changing this behavior is tricky, long-shot and difficult, but a little paragraph about this in documentation would be really nice. I am able to solve this at my code level. But for the future references or future implementations or just because I am curious what is your opinion of this behavior I created this issue in hope I will get an answer.

Thanks in advance Neloop

Very interesting issue. Thanks for the detailed explanation @Neloop !

@ammendonca i think we really need your input / feedback on something like this, to verify it really is (or not) the intended behaviour, before moving any further with discussion on potential ways to fix / PRs, and so on...