2929import com .hazelcast .raft .impl .RaftGroupIdImpl ;
3030import com .hazelcast .raft .service .semaphore .RaftSemaphoreService ;
3131import com .hazelcast .spi .InternalCompletableFuture ;
32+ import com .hazelcast .util .ConstructorFunction ;
3233
3334import java .util .UUID ;
3435import java .util .concurrent .TimeUnit ;
3536
3637import static com .hazelcast .client .impl .protocol .util .ParameterUtil .calculateDataSize ;
3738import static com .hazelcast .raft .impl .RaftGroupIdImpl .dataSize ;
39+ import static com .hazelcast .raft .service .atomiclong .client .AtomicLongMessageTaskFactoryProvider .ADD_AND_GET_TYPE ;
3840import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .ACQUIRE_PERMITS_TYPE ;
3941import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .AVAILABLE_PERMITS_TYPE ;
4042import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .CHANGE_PERMITS_TYPE ;
4345import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .DRAIN_PERMITS_TYPE ;
4446import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .INIT_SEMAPHORE_TYPE ;
4547import static com .hazelcast .raft .service .semaphore .client .SemaphoreMessageTaskFactoryProvider .RELEASE_PERMITS_TYPE ;
48+ import static com .hazelcast .raft .service .semaphore .proxy .GloballyUniqueThreadIdUtil .getGlobalThreadId ;
4649import static com .hazelcast .raft .service .session .AbstractSessionManager .NO_SESSION_ID ;
4750import static com .hazelcast .raft .service .util .ClientAccessor .getClient ;
4851import static com .hazelcast .util .Preconditions .checkNotNegative ;
5659public class RaftSessionlessSemaphoreProxy implements ISemaphore {
5760
5861 private static final ClientMessageDecoder INT_RESPONSE_DECODER = new IntResponseDecoder ();
62+ private static final ClientMessageDecoder LONG_RESPONSE_DECODER = new LongResponseDecoder ();
5963 private static final ClientMessageDecoder BOOLEAN_RESPONSE_DECODER = new BooleanResponseDecoder ();
6064
6165 public static ISemaphore create (HazelcastInstance instance , String name ) {
@@ -85,11 +89,32 @@ public RaftGroupId decodeClientMessage(ClientMessage msg) {
8589 private final HazelcastClientInstanceImpl client ;
8690 private final RaftGroupId groupId ;
8791 private final String name ;
92+ private final ConstructorFunction <RaftGroupId , Long > globallyUniqueThreadIdCtor ;
8893
89- private RaftSessionlessSemaphoreProxy (HazelcastInstance instance , RaftGroupId groupId , String name ) {
94+ private RaftSessionlessSemaphoreProxy (HazelcastInstance instance , RaftGroupId groupId , final String name ) {
9095 this .client = getClient (instance );
9196 this .groupId = groupId ;
9297 this .name = name ;
98+ this .globallyUniqueThreadIdCtor = new ConstructorFunction <RaftGroupId , Long >() {
99+ @ Override
100+ public Long createNew (RaftGroupId groupId ) {
101+ int dataSize = ClientMessage .HEADER_SIZE
102+ + RaftGroupIdImpl .dataSize (groupId ) + calculateDataSize (name )
103+ + Bits .LONG_SIZE_IN_BYTES ;
104+
105+ ClientMessage msg = ClientMessage .createForEncode (dataSize );
106+ msg .setMessageType (ADD_AND_GET_TYPE );
107+ msg .setRetryable (false );
108+ msg .setOperationName ("" );
109+ RaftGroupIdImpl .writeTo (groupId , msg );
110+ msg .set (name );
111+ msg .set (1L );
112+ msg .updateFrameLength ();
113+
114+ ClientInvocationFuture future = new ClientInvocation (client , msg , getName ()).invoke ();
115+ return new ClientDelegatingFuture <Long >(future , client .getSerializationService (), LONG_RESPONSE_DECODER ).join ();
116+ }
117+ };
93118 }
94119
95120 @ Override
@@ -115,10 +140,12 @@ public void acquire() {
115140 public void acquire (int permits ) {
116141 checkPositive (permits , "Permits must be positive!" );
117142
143+ long globalThreadId = getGlobalThreadId (groupId , globallyUniqueThreadIdCtor );
118144 UUID invocationUid = newUnsecureUUID ();
119- int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 4
145+ int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 5
120146 + Bits .INT_SIZE_IN_BYTES ;
121147 ClientMessage msg = prepareClientMessage (groupId , name , dataSize , ACQUIRE_PERMITS_TYPE );
148+ msg .set (globalThreadId );
122149 msg .set (invocationUid .getLeastSignificantBits ());
123150 msg .set (invocationUid .getMostSignificantBits ());
124151 msg .set (permits );
@@ -147,11 +174,13 @@ public boolean tryAcquire(long timeout, TimeUnit unit) {
147174 public boolean tryAcquire (int permits , long timeout , TimeUnit unit ) {
148175 checkPositive (permits , "Permits must be positive!" );
149176
177+ long globalThreadId = getGlobalThreadId (groupId , globallyUniqueThreadIdCtor );
150178 UUID invocationUid = newUnsecureUUID ();
151179 long timeoutMs = max (0 , unit .toMillis (timeout ));
152- int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 4
180+ int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 5
153181 + Bits .INT_SIZE_IN_BYTES ;
154182 ClientMessage msg = prepareClientMessage (groupId , name , dataSize , ACQUIRE_PERMITS_TYPE );
183+ msg .set (globalThreadId );
155184 msg .set (invocationUid .getLeastSignificantBits ());
156185 msg .set (invocationUid .getMostSignificantBits ());
157186 msg .set (permits );
@@ -171,10 +200,12 @@ public void release() {
171200 public void release (int permits ) {
172201 checkPositive (permits , "Permits must be positive!" );
173202
203+ long globalThreadId = getGlobalThreadId (groupId , globallyUniqueThreadIdCtor );
174204 UUID invocationUid = newUnsecureUUID ();
175- int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 3
205+ int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 4
176206 + Bits .INT_SIZE_IN_BYTES ;
177207 ClientMessage msg = prepareClientMessage (groupId , name , dataSize , RELEASE_PERMITS_TYPE );
208+ msg .set (globalThreadId );
178209 msg .set (invocationUid .getLeastSignificantBits ());
179210 msg .set (invocationUid .getMostSignificantBits ());
180211 msg .set (permits );
@@ -195,9 +226,11 @@ public int availablePermits() {
195226
196227 @ Override
197228 public int drainPermits () {
229+ long globalThreadId = getGlobalThreadId (groupId , globallyUniqueThreadIdCtor );
198230 UUID invocationUid = newUnsecureUUID ();
199- int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 3 ;
231+ int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 4 ;
200232 ClientMessage msg = prepareClientMessage (groupId , name , dataSize , DRAIN_PERMITS_TYPE );
233+ msg .set (globalThreadId );
201234 msg .set (invocationUid .getLeastSignificantBits ());
202235 msg .set (invocationUid .getMostSignificantBits ());
203236 msg .updateFrameLength ();
@@ -294,6 +327,13 @@ public Integer decodeClientMessage(ClientMessage msg) {
294327 }
295328 }
296329
330+ private static class LongResponseDecoder implements ClientMessageDecoder {
331+ @ Override
332+ public Long decodeClientMessage (ClientMessage msg ) {
333+ return msg .getLong ();
334+ }
335+ }
336+
297337 private static class BooleanResponseDecoder implements ClientMessageDecoder {
298338 @ Override
299339 public Boolean decodeClientMessage (ClientMessage msg ) {
0 commit comments