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