From e2842e1191dd25b95c54c8c3b6235f1137266cb5 Mon Sep 17 00:00:00 2001 From: rusefi Date: Fri, 24 Jul 2020 16:38:42 -0400 Subject: [PATCH] isUsed/owner progress --- .../com/rusefi/tools/online/ProxyClient.java | 2 ++ .../main/java/com/rusefi/server/Backend.java | 10 +++++----- .../com/rusefi/server/TwoKindSemaphore.java | 20 +++++++++++++++---- .../rusefi/server/TwoKindSemaphoreTest.java | 16 +++++++++++---- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/java_console/io/src/main/java/com/rusefi/tools/online/ProxyClient.java b/java_console/io/src/main/java/com/rusefi/tools/online/ProxyClient.java index d9185b94c2..f6a2dfe22f 100644 --- a/java_console/io/src/main/java/com/rusefi/tools/online/ProxyClient.java +++ b/java_console/io/src/main/java/com/rusefi/tools/online/ProxyClient.java @@ -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 getOnlineApplications(int httpPort) throws IOException { return getOnlineApplications(getHttpAddress(httpPort) + LIST_CONTROLLERS_PATH); diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java index fc16d93312..1dfa53da64 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java @@ -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()) diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/TwoKindSemaphore.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/TwoKindSemaphore.java index 20bc7b9052..27413cae75 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/TwoKindSemaphore.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/TwoKindSemaphore.java @@ -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; + } } diff --git a/java_tools/proxy_server/src/test/java/com/rusefi/server/TwoKindSemaphoreTest.java b/java_tools/proxy_server/src/test/java/com/rusefi/server/TwoKindSemaphoreTest.java index 05e884f9b2..48e80b7034 100644 --- a/java_tools/proxy_server/src/test/java/com/rusefi/server/TwoKindSemaphoreTest.java +++ b/java_tools/proxy_server/src/test/java/com/rusefi/server/TwoKindSemaphoreTest.java @@ -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()); } }