[ https://issues.apache.org/jira/browse/ARTEMIS-3949?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17582915#comment-17582915 ]
Robbie Gemmell commented on ARTEMIS-3949: ----------------------------------------- What you are asking for is for the session+children implementation to actually be made safe for use from multiple threads, which it isnt currently and is clearly not meant to be. What is in place with the counter is a form of helper/warning system to potentially advise that you are using multiple threads where you should not be doing so. I would expect the current behaviour stems directly from or was influenced by the explicit JMS threading model where a given Session and its child producers/consumers are expressly single threaded (even such that using a MessageListener on a MessageConsumer renders the parent Session to be dedicated to the session-wide listener thread). Applications do have to know which thread of theirs is using a Session and its related objects, including for acknowledgement (which operates on the session). If you are handing messages from one session out to multiple other threads for processing, you do need to similarly coordinate things back the way for acknowledgement. Nothing is forced to synchronise on the session object itself however vs using some external means for coordination. There are other alternatives to doing any such thread coordination like use of multiple sessions, of if lengthy parallel processing isnt an issue perhaps just use of multiple listeners on a single session. > Internally synchronize methods in ClientSession implementations > --------------------------------------------------------------- > > Key: ARTEMIS-3949 > URL: https://issues.apache.org/jira/browse/ARTEMIS-3949 > Project: ActiveMQ Artemis > Issue Type: Improvement > Components: ActiveMQ-Artemis-Native > Affects Versions: 2.24.0 > Reporter: Peter Machon > Assignee: Clebert Suconic > Priority: Major > > {{ClientSessionImpl}} has two internal functions i.e. {{startCall}} and > {{{}endCall{}}}. These function count concurrent access and throw in case of > concurrent access. > They are used e.g. in {{{}ClientProducerImpl{}}}s {{doSend}} method and in > the {{ClientSessionImpls}} {{acknowledge}} method. > This forces user code to synchronize the use of the session object. That is a > pain for two reasons: > 1. From a user perspective it is not even clear, which methods are internally > counting concurrent access. E.g. the `doSend` method does not even belong to > the session. > 2. The session object is not accessible from the user code at any time. E.g. > the {{ClientMessageImpl}} internally uses the {{{}ClientSession{}}}s > {{acknowledge}} method. From user code it is not necessarily clear which > session the `ClientMessage` belongs to. > Thus, it would require user code to e.g. implement their own message store > just to be able to synchronize the right session. > Solution: > The {{ClientSessionImpl}} and all other internal objects like > {{{}ClientProducerImpl, ClientMessageImpl{}}}, and similar have full access > and knowledge about their synchronization needs. > I thus suggest to implement synchronization where needed instead of leaving > the user alone with this issue, where the solution actually means to > reimplement a lot of functionality of the client. > E.g. > {{startCall();}} > {{try {}} > {{sessionContext.sendACK(false, blockOnAcknowledge, consumer, message);}} > {{} finally {}} > {{endCall();}} > > could be replaced with something like > {{synchronized(this) {}} > {{sessionContext.sendACK(false, blockOnAcknowledge, consumer, message);}} > {{} }} > -- This message was sent by Atlassian Jira (v8.20.10#820010)