2929import com .hazelcast .raft .RaftGroupId ;
3030import com .hazelcast .raft .impl .RaftGroupIdImpl ;
3131import com .hazelcast .raft .impl .session .SessionExpiredException ;
32- import com .hazelcast .raft .service .lock .RaftLockService ;
3332import com .hazelcast .raft .service .exception .WaitKeyCancelledException ;
33+ import com .hazelcast .raft .service .lock .RaftLockOwnershipState ;
34+ import com .hazelcast .raft .service .lock .RaftLockService ;
3435import com .hazelcast .raft .service .session .SessionAwareProxy ;
3536import com .hazelcast .raft .service .session .SessionManagerProvider ;
3637import com .hazelcast .spi .InternalCompletableFuture ;
37- import com .hazelcast .util .UuidUtil ;
3838
3939import java .util .UUID ;
4040import java .util .concurrent .TimeUnit ;
4141import java .util .concurrent .locks .Condition ;
4242
4343import static com .hazelcast .client .impl .protocol .util .ParameterUtil .calculateDataSize ;
4444import static com .hazelcast .raft .impl .RaftGroupIdImpl .dataSize ;
45- import static com .hazelcast .raft .service .lock .RaftLockService .INVALID_FENCE ;
4645import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .CREATE_TYPE ;
4746import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .DESTROY_TYPE ;
4847import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .FORCE_UNLOCK_TYPE ;
49- import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .LOCK_COUNT_TYPE ;
50- import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .LOCK_FENCE_TYPE ;
48+ import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .LOCK_OWNERSHIP_STATE ;
5149import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .LOCK_TYPE ;
5250import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .TRY_LOCK_TYPE ;
5351import static com .hazelcast .raft .service .lock .client .LockMessageTaskFactoryProvider .UNLOCK_TYPE ;
5452import static com .hazelcast .raft .service .session .AbstractSessionManager .NO_SESSION_ID ;
5553import static com .hazelcast .raft .service .util .ClientAccessor .getClient ;
5654import static com .hazelcast .util .ThreadUtil .getThreadId ;
55+ import static com .hazelcast .util .UuidUtil .newUnsecureUUID ;
5756
5857/**
5958 * TODO: Javadoc Pending...
6059 */
6160public class RaftLockProxy extends SessionAwareProxy implements ILock {
6261
63- static final ClientMessageDecoder INT_RESPONSE_DECODER = new IntResponseDecoder ();
6462 static final ClientMessageDecoder BOOLEAN_RESPONSE_DECODER = new BooleanResponseDecoder ();
65- static final ClientMessageDecoder LONG_RESPONSE_DECODER = new LongResponseDecoder ();
63+ static final ClientMessageDecoder LOCK_OWNERSHIP_STATE_RESPONSE_DECODER = new RaftLockOwnershipStateResponseDecoder ();
6664
6765 public static ILock create (HazelcastInstance instance , String name ) {
6866 int dataSize = ClientMessage .HEADER_SIZE + calculateDataSize (name );
@@ -101,12 +99,14 @@ private RaftLockProxy(HazelcastInstance instance, RaftGroupId groupId, String na
10199
102100 @ Override
103101 public void lock () {
104- UUID invUid = UuidUtil . newUnsecureUUID ();
102+ UUID invUid = newUnsecureUUID ();
105103 for (;;) {
106104 long sessionId = acquireSession ();
107105 ClientMessage msg = encodeRequest (LOCK_TYPE , groupId , name , sessionId , getThreadId (), invUid );
108106 try {
109- invoke (client , name , msg , LONG_RESPONSE_DECODER ).join ();
107+ RaftLockOwnershipState ownership = RaftLockProxy .<RaftLockOwnershipState >invoke (client , name , msg ,
108+ LOCK_OWNERSHIP_STATE_RESPONSE_DECODER ).join ();
109+ assert ownership .isLocked ();
110110 break ;
111111 } catch (SessionExpiredException e ) {
112112 invalidateSession (sessionId );
@@ -121,18 +121,18 @@ public boolean tryLock() {
121121
122122 @ Override
123123 public boolean tryLock (long time , TimeUnit unit ) {
124- UUID invUid = UuidUtil . newUnsecureUUID ();
124+ UUID invUid = newUnsecureUUID ();
125125 long timeoutMs = Math .max (0 , unit .toMillis (time ));
126126 for (;;) {
127127 long sessionId = acquireSession ();
128128 ClientMessage msg = encodeRequest (TRY_LOCK_TYPE , groupId , name , sessionId , getThreadId (), invUid , timeoutMs );
129129 try {
130- InternalCompletableFuture < Long > future = invoke (client , name , msg , LONG_RESPONSE_DECODER );
131- boolean locked = ( future .join () != INVALID_FENCE );
132- if (! locked ) {
133- releaseSession ( sessionId );
130+ RaftLockOwnershipState ownership = RaftLockProxy .< RaftLockOwnershipState > invoke (client , name , msg ,
131+ LOCK_OWNERSHIP_STATE_RESPONSE_DECODER ) .join ();
132+ if (ownership . isLocked () ) {
133+ return ownership . isLocked ( );
134134 }
135- return locked ;
135+ releaseSession ( sessionId ) ;
136136 } catch (WaitKeyCancelledException e ) {
137137 return false ;
138138 } catch (SessionExpiredException e ) {
@@ -147,8 +147,8 @@ public void unlock() {
147147 if (sessionId == NO_SESSION_ID ) {
148148 throw new IllegalMonitorStateException ();
149149 }
150- UUID invUid = UuidUtil . newUnsecureUUID ();
151- ClientMessage msg = encodeRequest (UNLOCK_TYPE , groupId , name , sessionId , getThreadId (), invUid );
150+ UUID invUid = newUnsecureUUID ();
151+ ClientMessage msg = encodeRequest (UNLOCK_TYPE , groupId , name , sessionId , getThreadId (), invUid , 1 );
152152 try {
153153 invoke (client , name , msg , BOOLEAN_RESPONSE_DECODER ).join ();
154154 } catch (SessionExpiredException e ) {
@@ -169,20 +169,23 @@ public boolean isLockedByCurrentThread() {
169169 if (sessionId == NO_SESSION_ID ) {
170170 return false ;
171171 }
172- ClientMessage msg = encodeRequest (LOCK_COUNT_TYPE , groupId , name , sessionId , getThreadId ());
173- InternalCompletableFuture <Integer > future = invoke (client , name , msg , INT_RESPONSE_DECODER );
174- return future .join () > 0 ;
172+
173+ ClientMessage msg = encodeRequest (LOCK_OWNERSHIP_STATE , groupId , name , -1 , -1 );
174+ InternalCompletableFuture <RaftLockOwnershipState > f = invoke (client , name , msg , LOCK_OWNERSHIP_STATE_RESPONSE_DECODER );
175+ RaftLockOwnershipState ownership = f .join ();
176+ return (ownership .getSessionId () == sessionId && ownership .getThreadId () == getThreadId ());
175177 }
176178
177179 @ Override
178180 public int getLockCount () {
179- ClientMessage msg = encodeRequest (LOCK_COUNT_TYPE , groupId , name , NO_SESSION_ID , 0 );
180- InternalCompletableFuture <Integer > future = invoke (client , name , msg , INT_RESPONSE_DECODER );
181- return future .join ();
181+ ClientMessage msg = encodeRequest (LOCK_OWNERSHIP_STATE , groupId , name , -1 , -1 );
182+ InternalCompletableFuture <RaftLockOwnershipState > f = invoke (client , name , msg , LOCK_OWNERSHIP_STATE_RESPONSE_DECODER );
183+ RaftLockOwnershipState ownership = f .join ();
184+ return ownership .getLockCount ();
182185 }
183186
184187 @ Override
185- public boolean tryLock (long time , TimeUnit unit , long leaseTime , TimeUnit leaseUnit ) throws InterruptedException {
188+ public boolean tryLock (long time , TimeUnit unit , long leaseTime , TimeUnit leaseUnit ) {
186189 throw new UnsupportedOperationException ();
187190 }
188191
@@ -193,15 +196,14 @@ public void lock(long leaseTime, TimeUnit timeUnit) {
193196
194197 @ Override
195198 public void forceUnlock () {
196- ClientMessage msg = encodeRequest (LOCK_FENCE_TYPE , groupId , name , -1 , -1 );
197- long fence = RaftLockProxy .<Long >invoke (client , name , msg , LONG_RESPONSE_DECODER ).join ();
198-
199- int dataSize = ClientMessage .HEADER_SIZE + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 5 ;
200- msg = prepareClientMessage (groupId , name , dataSize , FORCE_UNLOCK_TYPE );
201- setRequestParams (msg , -1 , -1 , UuidUtil .newUnsecureUUID ());
202- msg .set (fence );
203- msg .updateFrameLength ();
199+ ClientMessage msg = encodeRequest (LOCK_OWNERSHIP_STATE , groupId , name , -1 , -1 );
200+ RaftLockOwnershipState ownership = RaftLockProxy .<RaftLockOwnershipState >invoke (client , name , msg ,
201+ LOCK_OWNERSHIP_STATE_RESPONSE_DECODER ).join ();
202+ if (!ownership .isLocked ()) {
203+ throw new IllegalMonitorStateException ("Lock[" + name + "] has no owner!" );
204+ }
204205
206+ msg = encodeRequest (FORCE_UNLOCK_TYPE , groupId , name , -1 , -1 , newUnsecureUUID (), ownership .getFence ());
205207 invoke (client , name , msg , BOOLEAN_RESPONSE_DECODER ).join ();
206208 }
207209
@@ -221,7 +223,7 @@ public long getRemainingLeaseTime() {
221223 }
222224
223225 @ Override
224- public void lockInterruptibly () throws InterruptedException {
226+ public void lockInterruptibly () {
225227 throw new UnsupportedOperationException ();
226228 }
227229
@@ -270,6 +272,17 @@ static ClientMessage encodeRequest(int messageTypeId, RaftGroupId groupId, Strin
270272 return msg ;
271273 }
272274
275+ static ClientMessage encodeRequest (int messageTypeId , RaftGroupId groupId , String name , long sessionId ,
276+ long threadId , UUID invUid , int val ) {
277+ int dataSize = ClientMessage .HEADER_SIZE
278+ + dataSize (groupId ) + calculateDataSize (name ) + Bits .LONG_SIZE_IN_BYTES * 4 + Bits .INT_SIZE_IN_BYTES ;
279+ ClientMessage msg = prepareClientMessage (groupId , name , dataSize , messageTypeId );
280+ setRequestParams (msg , sessionId , threadId , invUid );
281+ msg .set (val );
282+ msg .updateFrameLength ();
283+ return msg ;
284+ }
285+
273286 static ClientMessage encodeRequest (int messageTypeId , RaftGroupId groupId , String name , long sessionId ,
274287 long threadId , UUID invUid , long val ) {
275288
@@ -309,24 +322,21 @@ static ClientMessage prepareClientMessage(RaftGroupId groupId, String name, int
309322 return msg ;
310323 }
311324
312- private static class IntResponseDecoder implements ClientMessageDecoder {
313- @ Override
314- public Integer decodeClientMessage (ClientMessage msg ) {
315- return msg .getInt ();
316- }
317- }
318-
319325 private static class BooleanResponseDecoder implements ClientMessageDecoder {
320326 @ Override
321327 public Boolean decodeClientMessage (ClientMessage msg ) {
322328 return msg .getBoolean ();
323329 }
324330 }
325331
326- private static class LongResponseDecoder implements ClientMessageDecoder {
332+ private static class RaftLockOwnershipStateResponseDecoder implements ClientMessageDecoder {
327333 @ Override
328- public Long decodeClientMessage (ClientMessage msg ) {
329- return msg .getLong ();
334+ public RaftLockOwnershipState decodeClientMessage (ClientMessage msg ) {
335+ long fence = msg .getLong ();
336+ int lockCount = msg .getInt ();
337+ long sessionId = msg .getLong ();
338+ long threadId = msg .getLong ();
339+ return new RaftLockOwnershipState (fence , lockCount , sessionId , threadId );
330340 }
331341 }
332342}
0 commit comments