isUsed/owner progress
This commit is contained in:
parent
e6f6868598
commit
e2842e1191
|
@ -18,6 +18,8 @@ public class ProxyClient {
|
|||
public static final String LIST_APPLICATIONS_PATH = "/list_applications";
|
||||
public static final String VERSION_PATH = "/version";
|
||||
public static final String BACKEND_VERSION = "0.0001";
|
||||
public static final String IS_USED = "isUsed";
|
||||
public static final String OWNER = "owner";
|
||||
|
||||
public static List<PublicSession> getOnlineApplications(int httpPort) throws IOException {
|
||||
return getOnlineApplications(getHttpAddress(httpPort) + LIST_CONTROLLERS_PATH);
|
||||
|
|
|
@ -41,7 +41,6 @@ public class Backend implements Closeable {
|
|||
|
||||
public static final int SERVER_PORT_FOR_CONTROLLERS = 8003;
|
||||
private static final String MAX_PACKET_GAP = "MAX_PACKET_GAP";
|
||||
private static final String IS_USED = "isUsed";
|
||||
|
||||
/**
|
||||
* Application with exclusive access should connect tuning application within 3 minutes
|
||||
|
@ -180,7 +179,7 @@ public class Backend implements Closeable {
|
|||
ControllerKey controllerKey = new ControllerKey(applicationRequest.getTargetUserId(), applicationRequest.getSessionDetails().getControllerInfo());
|
||||
ControllerConnectionState state;
|
||||
synchronized (lock) {
|
||||
state = acquire(controllerKey);
|
||||
state = acquire(controllerKey, userDetails);
|
||||
}
|
||||
if (state == null) {
|
||||
log.info("No controller for " + controllerKey);
|
||||
|
@ -203,14 +202,14 @@ public class Backend implements Closeable {
|
|||
}, serverPortForApplications, "ApplicationServer", serverSocketCreationCallback, BinaryProtocolServer.SECURE_SOCKET_FACTORY);
|
||||
}
|
||||
|
||||
private ControllerConnectionState acquire(ControllerKey controllerKey) {
|
||||
private ControllerConnectionState acquire(ControllerKey controllerKey, UserDetails userDetails) {
|
||||
synchronized (lock) {
|
||||
ControllerConnectionState state = controllersByKey.get(controllerKey);
|
||||
if (state == null) {
|
||||
// no such controller
|
||||
return null;
|
||||
}
|
||||
if (!state.getTwoKindSemaphore().acquireForLongTermUsage()) {
|
||||
if (!state.getTwoKindSemaphore().acquireForLongTermUsage(userDetails)) {
|
||||
// someone is already talking to this controller
|
||||
return null;
|
||||
}
|
||||
|
@ -279,7 +278,8 @@ public class Backend implements Closeable {
|
|||
JsonObject controllerObject = Json.createObjectBuilder()
|
||||
.add(UserDetails.USER_ID, client.getUserDetails().getUserId())
|
||||
.add(UserDetails.USERNAME, client.getUserDetails().getUserName())
|
||||
.add(IS_USED, client.getTwoKindSemaphore().isUsed())
|
||||
.add(ProxyClient.IS_USED, client.getTwoKindSemaphore().isUsed())
|
||||
.add(ProxyClient.OWNER, client.getTwoKindSemaphore().getOwner().getUserName())
|
||||
.add(ControllerStateDetails.RPM, rpm)
|
||||
.add(ControllerStateDetails.CLT, clt)
|
||||
.add(ControllerInfo.SIGNATURE, client.getSessionDetails().getControllerInfo().getSignature())
|
||||
|
|
|
@ -8,9 +8,12 @@ public class TwoKindSemaphore {
|
|||
private final static int LONG_TERM = 2;
|
||||
private final static int SHORT_TERM = 1;
|
||||
private final Semaphore semaphore = new Semaphore(LONG_TERM);
|
||||
private UserDetails owner;
|
||||
|
||||
public void releaseFromLongTermUsage() {
|
||||
semaphore.release(LONG_TERM);
|
||||
// not atomic but that's fine, isUsed is the source of truth
|
||||
owner = null;
|
||||
}
|
||||
|
||||
public boolean acquireForShortTermUsage() {
|
||||
|
@ -28,16 +31,25 @@ public class TwoKindSemaphore {
|
|||
|
||||
/**
|
||||
* @return true if acquired successfully, false if not
|
||||
* @param userDetails
|
||||
*/
|
||||
public boolean acquireForLongTermUsage() {
|
||||
return acquireForLongTermUsage(10);
|
||||
public boolean acquireForLongTermUsage(UserDetails userDetails) {
|
||||
return acquireForLongTermUsage(userDetails, 10);
|
||||
}
|
||||
|
||||
public boolean acquireForLongTermUsage(int timeout) {
|
||||
public boolean acquireForLongTermUsage(UserDetails userDetails, int timeout) {
|
||||
try {
|
||||
return semaphore.tryAcquire(LONG_TERM, timeout, TimeUnit.SECONDS);
|
||||
boolean isAcquired = semaphore.tryAcquire(LONG_TERM, timeout, TimeUnit.SECONDS);
|
||||
if (isAcquired) {
|
||||
owner = userDetails;
|
||||
}
|
||||
return isAcquired;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public UserDetails getOwner() {
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ package com.rusefi.server;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TwoKindSemaphoreTest {
|
||||
@Test
|
||||
|
@ -15,11 +14,20 @@ public class TwoKindSemaphoreTest {
|
|||
assertFalse(twoKindSemaphore.isUsed());
|
||||
twoKindSemaphore.releaseFromShortTermUsage();
|
||||
|
||||
assertNull(twoKindSemaphore.getOwner());
|
||||
|
||||
assertTrue(twoKindSemaphore.acquireForLongTermUsage());
|
||||
UserDetails userDetails = new UserDetails("xxx", 222);
|
||||
|
||||
|
||||
assertTrue(twoKindSemaphore.acquireForLongTermUsage(userDetails));
|
||||
assertNotNull(twoKindSemaphore.getOwner());
|
||||
assertTrue(twoKindSemaphore.isUsed());
|
||||
//
|
||||
assertFalse(twoKindSemaphore.acquireForLongTermUsage(1));
|
||||
assertFalse(twoKindSemaphore.acquireForLongTermUsage(userDetails, 1));
|
||||
assertFalse(twoKindSemaphore.acquireForShortTermUsage());
|
||||
|
||||
|
||||
twoKindSemaphore.releaseFromLongTermUsage();
|
||||
assertNull(twoKindSemaphore.getOwner());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue