Bug 576774: [RJ-Servi] Migrate to java.time API Also: - Rename some config properties to more meaningful names - Fix display names of properties in MXBeans Change-Id: I120cc837e51e321f01ca06122c103ce2d3d96b37
diff --git a/CHANGES.md b/CHANGES.md index 558c592..2e0951f 100644 --- a/CHANGES.md +++ b/CHANGES.md
@@ -3,6 +3,8 @@ ## RJ 4.5.0 ~ StatET 4.5.0 +### Services + * The data access for tool command handler is enhanced. Implementations of handlers need to be adapted. @@ -13,6 +15,15 @@ (Bug 574779) +### RServi Node and Pool + + * The configuration and pool API is migrated to make use of `java.time`. Timestamps are + represented by `Instant` and durations like timeouts by `Duration`, except in MXBeans. + In the config classes also some related properties are renamed to more meaningful names. + For property accessors, which still use long for timestamps and durations, the postfix `Millis` + is added to their names. + Applications need to be adapted. (Bug 576774) + ## RJ 4.4.0 ~ StatET 4.4.0
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java index a7ea932..24b2e91 100644 --- a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java +++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/JMPoolTest.java
@@ -14,8 +14,6 @@ package org.eclipse.statet.rj.servi.pool; -import static java.util.concurrent.TimeUnit.NANOSECONDS; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -28,6 +26,7 @@ import static org.eclipse.statet.internal.rj.servi.APool2.CLIENT_ALLOCATION_RENEW_PERIOD_MILLIS_PROPERTY_KEY; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; @@ -36,6 +35,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; +import java.util.function.Supplier; import javax.security.auth.login.LoginException; @@ -70,9 +70,9 @@ public class JMPoolTest extends AbstractServiTest { - private static int NODE_STARTUP_MILLIS= 7_000; + private static Duration NODE_STARTUP_DURATION= Duration.ofSeconds(7); - private static int WAIT_IDLE_MILLIS= 30_000; + private static Duration WAIT_IDLE_DURATION= Duration.ofSeconds(30); private static double TIME_TOLERANCE_MILLIS= 10; @@ -230,7 +230,7 @@ } @Test - public void TotalNodes_borrowMax() throws Exception, + public void TotalNodes_allocateMax() throws Exception, InterruptedException { final PoolConfig poolConfig= new PoolConfig(); poolConfig.setMaxTotalCount(2); @@ -243,7 +243,7 @@ assertNodeOperative(servi1); assertNodeOperative(servi2); - Thread.sleep(WAIT_IDLE_MILLIS); + Thread.sleep(WAIT_IDLE_DURATION.toMillis()); assertIdleCount(0); closeServi(servi1); @@ -251,11 +251,12 @@ } @Test - public void TotalNodes_borrowTimeout() throws Exception { + public void TotalNodes_allocateTimeout() throws Exception { final PoolConfig poolConfig= new PoolConfig(); poolConfig.setMaxTotalCount(2); this.server.setPoolConfig(poolConfig); this.server.start(); + final var timeout= nonNullAssert(poolConfig.getAllocationTimeout()); final RServi servi1= getServi("test1"); assertNotNull(servi1); @@ -263,10 +264,10 @@ final long t2= System.nanoTime(); final RServi servi2= getServi("test2"); assertNotNull(servi2); - { final long d2= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t2); - final long dMax= poolConfig.getMaxWaitTime() + NODE_STARTUP_MILLIS; - assertTrue(d2 < dMax, - () -> String.format("duration expected: < %1$sms, actual: %2$sms", dMax, d2) ); + { final Duration d2= Duration.ofNanos(System.nanoTime() - t2); + final Duration dMax= timeout.plus(NODE_STARTUP_DURATION); + assertTrue(d2.compareTo(dMax) < 0, () -> + String.format("duration expected: < %1$sms, actual: %2$sms", dMax, d2) ); } final long t3= System.nanoTime(); @@ -276,16 +277,17 @@ throw new AssertionError("totalCount"); } catch (final NoSuchElementException e) { - final long d3= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t3); - final long dExpected= poolConfig.getMaxWaitTime(); - final long dTol= 500; - assertTrue(d3 > poolConfig.getMaxWaitTime() - dTol && d3 < poolConfig.getMaxWaitTime() + dTol, - () -> String.format("duration expected: %1$sms (±%3$sms), actual: %2$sms", dExpected, d3, dTol)); + final Duration d3= Duration.ofNanos(System.nanoTime() - t3); + final Duration dExpected= timeout; + final double deltaMillis= 500; + assertDurationEquals(dExpected, d3, deltaMillis, () -> + String.format("duration expected: %1$sms (±%3$sms), actual: %2$sms", + dExpected, d3, deltaMillis )); } } @Test - public void UsageCount_borrowMax() throws Exception { + public void UsageCount_allocateMax() throws Exception { final ProgressMonitor m1= new NullProgressMonitor(); final ProgressMonitor m2= new NullProgressMonitor(); @@ -327,7 +329,7 @@ final PoolNodeObject node1= assertSinglePoolNode(); awaitStateCondition(node1, (state) -> (state != PoolNodeState.ALLOCATED), - (int)(1.2 * periodMillis) + WAIT_IDLE_MILLIS ); + Duration.ofMillis((long)(1.2 * periodMillis)).plus(WAIT_IDLE_DURATION) ); skipChecking(node1); assertEquals(PoolNodeState.ALLOCATED, node1.getState()); assertNodeOperative(servi1); @@ -359,7 +361,7 @@ clientCheckJob.cancel(false); awaitStateCondition(node1, (state) -> (state != PoolNodeState.ALLOCATED), - (int)(1.2 * periodMillis) + WAIT_IDLE_MILLIS ); + Duration.ofMillis((long)(1.2 * periodMillis)).plus(WAIT_IDLE_DURATION) ); skipChecking(node1); assertDisposingToDisposed(node1); @@ -463,7 +465,7 @@ skipChecking(node1); assertEquals(PoolNodeState.IDLING, node1.getState()); - node1.evict(0); + node1.evict(null); assertDisposingToDisposed(node1); } @@ -514,22 +516,31 @@ this.server.setPoolConfig(poolConfig); this.server.start(); + Duration actual; + assertIdleCount(1); final PoolNodeObject node1= assertSinglePoolNode(); - assertEquals(-1, node1.getLastestAllocationDuration(), "duration"); + actual= node1.getLastestAllocationDuration(); + assertNull(actual, "duration"); final long startNanos= System.nanoTime(); final RServi servi1= getServi("test1"); - assertEquals(NANOSECONDS.toMillis(System.nanoTime() - startNanos), node1.getLastestAllocationDuration(), + actual= node1.getLastestAllocationDuration(); + assertNotNull(actual); + assertDurationEquals(Duration.ofNanos(System.nanoTime() - startNanos), actual, TIME_TOLERANCE_MILLIS, "duration" ); Thread.sleep(3000); - assertEquals(NANOSECONDS.toMillis(System.nanoTime() - startNanos), node1.getLastestAllocationDuration(), + actual= node1.getLastestAllocationDuration(); + assertNotNull(actual); + assertDurationEquals(Duration.ofNanos(System.nanoTime() - startNanos), actual, TIME_TOLERANCE_MILLIS, "duration" ); final long endNanos= System.nanoTime(); closeServi(servi1); - assertEquals(NANOSECONDS.toMillis(endNanos - startNanos), node1.getLastestAllocationDuration(), + actual= node1.getLastestAllocationDuration(); + assertNotNull(actual); + assertDurationEquals(Duration.ofNanos(endNanos - startNanos), actual, TIME_TOLERANCE_MILLIS, "duration" ); } @@ -546,7 +557,7 @@ final PoolNodeObject node1= assertSinglePoolNode(); closeServi(servi1); - node1.evict(0); + node1.evict(null); skipChecking(node1); assertDisposingToDisposed(node1); @@ -564,7 +575,7 @@ final PoolNodeObject node1= assertSinglePoolNode(); assertEquals(PoolNodeState.ALLOCATED, node1.getState()); - node1.evict(0); + node1.evict(null); skipChecking(node1); assertDisposingToDisposed(node1); @@ -602,7 +613,7 @@ } final PoolNodeObject node1= assertSinglePoolNode(); assertEquals(PoolNodeState.ALLOCATED, node1.getState()); - node1.evict(0); + node1.evict(null); skipChecking(node1); assertDisposingToDisposed(node1); @@ -626,7 +637,7 @@ final Process process= nonNullAssert((Process)nodeHandler.getFieldObj("process")); process.destroy(); - node1.evict(0); + node1.evict(null); skipChecking(node1); assertDisposingToDisposed(node1); @@ -663,7 +674,7 @@ if (expected == poolStatus.getNumIdling()) { return; } - if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t) > WAIT_IDLE_MILLIS) { + if (System.nanoTime() - t > WAIT_IDLE_DURATION.toNanos()) { assertEquals(expected, poolStatus.getNumIdling(), "num idle"); } Thread.sleep(100); @@ -671,17 +682,17 @@ } private void skipChecking(final PoolNodeObject node) throws InterruptedException { - awaitStateCondition(node, (state) -> (state != PoolNodeState.CHECKING), WAIT_IDLE_MILLIS); + awaitStateCondition(node, (state) -> (state != PoolNodeState.CHECKING), WAIT_IDLE_DURATION); } private void awaitStateCondition(final PoolNodeObject node, - final Predicate<PoolNodeState> condition, final int timeoutMillis) throws InterruptedException { + final Predicate<PoolNodeState> condition, final Duration timeout) throws InterruptedException { final long t= System.nanoTime(); while (true) { if (condition.test(node.getState())) { return; } - if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t) > timeoutMillis) { + if (System.nanoTime() - t > timeout.toNanos()) { return; } Thread.sleep(100); @@ -696,9 +707,19 @@ assertEquals(PoolNodeState.DISPOSING, state, "state"); } - awaitStateCondition(node, (state) -> (state != PoolNodeState.DISPOSING), WAIT_IDLE_MILLIS); + awaitStateCondition(node, (state) -> (state != PoolNodeState.DISPOSING), WAIT_IDLE_DURATION); assertEquals(PoolNodeState.DISPOSED, node.getState(), "state"); } + private void assertDurationEquals(final Duration expected, final Duration actual, + final double deltaMillis, final String message) { + assertEquals(expected.toMillis(), actual.toMillis(), deltaMillis, message); + } + + private void assertDurationEquals(final Duration expected, final Duration actual, + final double deltaMillis, final Supplier<String> messageSupplier) { + assertEquals(expected.toMillis(), actual.toMillis(), deltaMillis, messageSupplier); + } + }
diff --git a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java index 8371cb5..96527cc 100644 --- a/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java +++ b/servi/org.eclipse.statet.rj.servi-tests/src/org/eclipse/statet/rj/servi/pool/LocalNodeTest.java
@@ -20,8 +20,8 @@ import java.nio.file.Files; import java.nio.file.Path; +import java.time.Duration; import java.util.NoSuchElementException; -import java.util.concurrent.TimeUnit; import javax.management.OperationsException; import javax.security.auth.login.LoginException; @@ -191,9 +191,9 @@ final long t1= System.nanoTime(); this.localR.stop(); - final long d1= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1); - final long dMax= new RServiNodeConfig().getStartStopTimeout() + 1500; - assertTrue(d1 < new RServiNodeConfig().getStartStopTimeout() + 1500, + final Duration d1= Duration.ofNanos(System.nanoTime() - t1); + final Duration dMax= new RServiNodeConfig().getStartStopTimeout().plusMillis(1500); + assertTrue(d1.compareTo(dMax) < 0, () -> String.format("duration expected: < %1$sms, actual: %2$sms", dMax, d1) ); }
diff --git a/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolItemBean.java b/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolItemBean.java index dfe0447..3ca6878 100644 --- a/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolItemBean.java +++ b/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolItemBean.java
@@ -14,6 +14,10 @@ package org.eclipse.statet.rj.servi.webapp; +import java.time.Instant; + +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; import org.eclipse.statet.jcommons.rmi.RMIAddress; import org.eclipse.statet.rj.RjException; @@ -23,21 +27,22 @@ import org.eclipse.statet.rj.servi.pool.PoolServer; +@NonNullByDefault public class PoolItemBean extends PoolNodeItem { - public PoolItemBean(final PoolNodeObject poolObj, final long stamp) { + public PoolItemBean(final PoolNodeObject poolObj, final Instant stamp) { super(poolObj, stamp); } - public String getRMIAddress() { + public @Nullable String getRMIAddress() { final RMIAddress address= getAddress(); return (address != null) ? address.getAddress() : null; } - public String actionEnableConsole() { + public @Nullable String actionEnableConsole() { try { super.enableConsole("none"); } @@ -47,7 +52,7 @@ return null; } - public String actionDisableConsole() { + public @Nullable String actionDisableConsole() { try { super.disableConsole(); } @@ -67,7 +72,7 @@ } public void actionKill() { - evict(0); + evict(null); } }
diff --git a/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolStatusBean.java b/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolStatusBean.java index bb23c7f..1800e8a 100644 --- a/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolStatusBean.java +++ b/servi/org.eclipse.statet.rj.servi.webapp/src/main/java/org/eclipse/statet/rj/servi/webapp/PoolStatusBean.java
@@ -14,14 +14,20 @@ package org.eclipse.statet.rj.servi.webapp; +import java.time.Instant; + import javax.annotation.PostConstruct; +import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; + import org.eclipse.statet.rj.servi.pool.PoolNodeItem; import org.eclipse.statet.rj.servi.pool.PoolNodeObject; import org.eclipse.statet.rj.servi.pool.PoolStatus; import org.eclipse.statet.rj.servi.pool.RServiPoolManager; +@NonNullByDefault public class PoolStatusBean extends PoolStatus<PoolItemBean> { @@ -40,7 +46,7 @@ } private void load() { - final long stamp= System.currentTimeMillis(); + final Instant stamp= Instant.now(); final RServiPoolManager poolManager= this.server.getManager(); if (poolManager == null) { FacesUtils.addErrorMessage(null, "The pool is currently not available."); @@ -49,7 +55,7 @@ } @Override - protected PoolNodeItem createPoolItem(final PoolNodeObject itemData, final long stamp) { + protected PoolNodeItem createPoolItem(final PoolNodeObject itemData, final Instant stamp) { return new PoolItemBean(itemData, stamp); } @@ -59,7 +65,7 @@ } - public synchronized long getStamp() { + public synchronized Instant getStamp() { check(); return super.getStatusStamp(); } @@ -76,16 +82,16 @@ } - public String actionRefresh() { + public @Nullable String actionRefresh() { return null; } - public synchronized String actionEnableAutoRefresh() { + public synchronized @Nullable String actionEnableAutoRefresh() { this.autoRefresh= true; return null; } - public synchronized String actionDisableAutoRefresh() { + public synchronized @Nullable String actionDisableAutoRefresh() { this.autoRefresh= false; return null; }
diff --git a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/LocalNodeFactory.java b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/LocalNodeFactory.java index 5737c0e..464a3a0 100644 --- a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/LocalNodeFactory.java +++ b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/LocalNodeFactory.java
@@ -425,15 +425,12 @@ p.rStartupSnippet= config.getRStartupSnippet(); - long timeout= config.getStartStopTimeout(); - if (timeout > 0) { - timeout= TimeUnit.MILLISECONDS.toNanos(timeout); - } + final var timeout= config.getStartStopTimeout(); synchronized (this) { this.verbose= config.getEnableVerbose(); this.baseConfig= config; this.processConfig= p; - this.timeoutNanos= timeout; + this.timeoutNanos= (timeout != null) ? timeout.toNanos() : -1; } }
diff --git a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/NodeHandler.java b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/NodeHandler.java index 892e741..b5a66f0 100644 --- a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/NodeHandler.java +++ b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/NodeHandler.java
@@ -19,6 +19,7 @@ import java.nio.file.Path; import java.rmi.RemoteException; +import java.time.Instant; import org.eclipse.statet.jcommons.lang.NonNullByDefault; import org.eclipse.statet.jcommons.lang.Nullable; @@ -47,11 +48,10 @@ boolean isConsoleEnabled; - private long shutdownTime; + private @Nullable Instant shutdownTime; public NodeHandler() { - this.shutdownTime= -1; } @@ -111,7 +111,7 @@ } void shutdown() throws RemoteException { - this.shutdownTime= System.currentTimeMillis(); + this.shutdownTime= Instant.now(); this.clientHandler= null; setClientLabel(null); final RServiNode node= this.node; @@ -137,7 +137,10 @@ return this.clientLabel; } - public long getShutdownTime() { + /** + * @since 4.5 + */ + public @Nullable Instant getShutdownTime() { return this.shutdownTime; }
diff --git a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/Utils.java b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/Utils.java index d0f817a..65e1426 100644 --- a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/Utils.java +++ b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/internal/rj/servi/Utils.java
@@ -16,6 +16,7 @@ import static org.eclipse.statet.jcommons.lang.SystemUtils.OS_WIN; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -191,6 +192,74 @@ } + public static boolean isNegative(final @Nullable Duration duration) { + return (duration != null && duration.isNegative()); + } + + + private static boolean isSign(final char c) { + return (c == '+' || c == '-'); + } + + private static boolean isDigit(final char c) { + return (c >= '0' && c <= '9'); + } + + public static Duration parseDuration(final String s) { + if (!s.isEmpty() + && (isSign(s.charAt(0)) ? + s.length() >= 2 && isDigit(s.charAt(1)) : + isDigit(s.charAt(0)) )) { + final long millis= Long.parseLong(s); + return Duration.ofMillis(millis); + } + return Duration.parse(s); + } + + public static Duration parseDuration(final @Nullable String s, + final Duration defaultValue) { + if (s == null) { + return defaultValue; + } + return parseDuration(s); + } + + public static String serDuration(final Duration duration) { + return Long.toString(duration.toMillis()); + } + + public static @Nullable Duration parseNullableDuration(final String s) { + if (s.isEmpty()) { + return null; + } + if ((isSign(s.charAt(0)) ? + s.length() >= 2 && isDigit(s.charAt(1)) : + isDigit(s.charAt(0)) )) { + final long millis= Long.parseLong(s); + if (millis == -1) { + return null; + } + return Duration.ofMillis(millis); + } + return Duration.parse(s); + } + + public static @Nullable Duration parseNullableDuration(final @Nullable String s, + final Duration defaultValue) { + if (s == null) { + return defaultValue; + } + return parseNullableDuration(s); + } + + public static String serNullableDuration(final @Nullable Duration duration) { + if (duration == null) { + return "-1"; // for backward compatibility //$NON-NLS-1$ + } + return Long.toString(duration.toMillis()); + } + + private Utils() { }
diff --git a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/rj/servi/node/RServiNodeConfig.java b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/rj/servi/node/RServiNodeConfig.java index 2f8d245..4f15f9f 100644 --- a/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/rj/servi/node/RServiNodeConfig.java +++ b/servi/org.eclipse.statet.rj.servi/src/org/eclipse/statet/rj/servi/node/RServiNodeConfig.java
@@ -14,10 +14,13 @@ package org.eclipse.statet.rj.servi.node; +import static org.eclipse.statet.internal.rj.servi.Utils.isNegative; + import java.io.File; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; +import java.time.Duration; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -73,11 +76,12 @@ * Property id for timeout of start/stop of nodes * * @see #setStartStopTimeout(long) - * @since 2.0 */ - public static final String STARTSTOP_TIMEOUT__ID= "startstop_timeout.millis"; + public static final String STARTSTOP_TIMEOUT_ID= "startstop_timeout.millis"; + @Deprecated + public static final String STARTSTOP_TIMEOUT__ID= STARTSTOP_TIMEOUT_ID; - private static final long STARTSTOP_TIMEOUT_DEFAULT= 10 * 1000; + private static final Duration STARTSTOP_TIMEOUT_DEFAULT= Duration.ofSeconds(10); private @Nullable String rHome; @@ -96,7 +100,7 @@ private boolean enableConsole; private boolean enableVerbose; - private long startStopTimeout; + private @Nullable Duration startStopTimeout; public RServiNodeConfig() { @@ -174,11 +178,13 @@ setNodeArgs(map.getProperty(NODE_ARGS_ID)); setBaseWorkingDirectory(map.getProperty(BASE_WD_ID)); setRStartupSnippet(map.getProperty(R_STARTUP_SNIPPET_ID)); - setEnableConsole(Boolean.parseBoolean(map.getProperty(CONSOLE_ENABLED_ID))); - setEnableVerbose(Boolean.parseBoolean(map.getProperty(VERBOSE_ENABLED_ID))); - { final String s= map.getProperty(STARTSTOP_TIMEOUT__ID); - this.startStopTimeout= ((s != null) ? Long.parseLong(s) : STARTSTOP_TIMEOUT_DEFAULT); - } + setEnableConsole(Boolean.parseBoolean( + map.getProperty(CONSOLE_ENABLED_ID) )); + setEnableVerbose(Boolean.parseBoolean( + map.getProperty(VERBOSE_ENABLED_ID) )); + this.startStopTimeout= Utils.parseNullableDuration( + map.getProperty(STARTSTOP_TIMEOUT_ID), + STARTSTOP_TIMEOUT_DEFAULT ); } @Override @@ -195,7 +201,7 @@ Utils.setProperty(map, R_STARTUP_SNIPPET_ID, this.rStartupSnippet); Utils.setProperty(map, CONSOLE_ENABLED_ID, Boolean.toString(this.enableConsole)); Utils.setProperty(map, VERBOSE_ENABLED_ID, Boolean.toString(this.enableVerbose)); - Utils.setProperty(map, STARTSTOP_TIMEOUT__ID, Long.toString(this.startStopTimeout)); + Utils.setProperty(map, STARTSTOP_TIMEOUT_ID, Utils.serNullableDuration(this.startStopTimeout)); } public synchronized void setRHome(final @Nullable String path) { @@ -311,23 +317,23 @@ /** * Returns the timeout of start/stop of nodes * - * @return the timeout in milliseconds + * @return the timeout or {@code null} if timeout is disabled * - * @since 2.0 + * @since 4.5 */ - public long getStartStopTimeout() { + public synchronized @Nullable Duration getStartStopTimeout() { return this.startStopTimeout; } /** * Sets the timeout of start/stop of nodes * - * @param milliseconds the timeout in milliseconds + * @param timeout the timeout (> 0) or {@code null} to disable timeout * - * @since 2.0 + * @since 4.5 */ - public void setStartStopTimeout(final long milliseconds) { - this.startStopTimeout= milliseconds; + public synchronized void setStartStopTimeout(final @Nullable Duration timeout) { + this.startStopTimeout= timeout; } @@ -339,9 +345,9 @@ valid&= isDirectoryPropertyValid(JAVA_HOME_ID, this.javaHome, messages); valid&= isDirectoryPropertyValid(BASE_WD_ID, this.baseWd, messages); - if (this.startStopTimeout != -1 && this.startStopTimeout < 0) { + if (isNegative(this.startStopTimeout)) { if (messages != null) { - messages.add(new ValidationMessage(STARTSTOP_TIMEOUT__ID, "Value must be > 0 or -1 (infinite).")); + messages.add(new ValidationMessage(STARTSTOP_TIMEOUT_ID, "Value must be > 0 or unset/-1 (infinite).")); } valid= false; }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java index c1ee7e9..0a298f6 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2.java
@@ -14,6 +14,10 @@ package org.eclipse.statet.internal.rj.servi; +import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullElse; + +import java.time.Duration; + import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectState; import org.apache.commons.pool2.impl.DefaultEvictionPolicy; @@ -24,6 +28,7 @@ import org.eclipse.statet.jcommons.collections.ImList; import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; import org.eclipse.statet.rj.RjInvalidConfigurationException; import org.eclipse.statet.rj.servi.pool.PoolConfig; @@ -44,6 +49,8 @@ private static final byte CLOSED= 4; + private static final Duration DISABLE_DURATION= Duration.ofMillis(-1); + private static final EvictionPolicy<APool2NodeHandler> EVICTION_POLICY= new DefaultEvictionPolicy<>() { @Override @@ -65,14 +72,14 @@ aConfig.setTestOnBorrow(false); aConfig.setBlockWhenExhausted(true); aConfig.setMaxTotal(config.getMaxTotalCount()); - aConfig.setMaxWaitMillis(config.getMaxWaitTime()); + aConfig.setMaxWait(nonNullElse(config.getAllocationTimeout(), DISABLE_DURATION)); aConfig.setMinIdle(config.getMinIdleCount()); aConfig.setMaxIdle(config.getMaxIdleCount()); - aConfig.setMinEvictableIdleTimeMillis(0); - aConfig.setSoftMinEvictableIdleTimeMillis(config.getMinIdleTime()); - aConfig.setTimeBetweenEvictionRunsMillis(5000); + aConfig.setMinEvictableIdleTime(Duration.ZERO); + aConfig.setSoftMinEvictableIdleTime(config.getAutoEvictionMinIdleTime()); + aConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(5)); aConfig.setNumTestsPerEvictionRun(-4); - aConfig.setEvictorShutdownTimeoutMillis(0); + aConfig.setEvictorShutdownTimeout(Duration.ZERO); return aConfig; } @@ -165,7 +172,7 @@ throw new UnsupportedOperationException(); } - public void close(final long evictionTimeout) { + public void close(final @Nullable Duration evictionTimeout) { synchronized (this.stateLock) { if (this.state > CLOSING) { return; @@ -173,7 +180,7 @@ this.state= CLOSING; } final long evictNanos= APool2NodeHandler.evictNanos(evictionTimeout); - final boolean evictDirect= (evictionTimeout == 0); + final boolean evictDirect= (evictionTimeout == null); try { Thread.sleep(10); @@ -191,7 +198,12 @@ return; } setNumTestsPerEvictionRun(512); - setTimeBetweenEvictionRunsMillis(500); + setTimeBetweenEvictionRuns(Duration.ofMillis(500)); + } + + @Deprecated(since= "4.5") + public void close(final long evictionTimeout) { + close((evictionTimeout == 0) ? null : Duration.ofMillis(evictionTimeout)); } protected void closeFinally() {
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeHandler.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeHandler.java index fe664e8..9618fb4 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeHandler.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeHandler.java
@@ -16,6 +16,8 @@ import java.rmi.Remote; import java.rmi.RemoteException; +import java.time.Duration; +import java.time.Instant; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectState; @@ -37,10 +39,10 @@ return (nanos != 0) ? nanos : 1; } - static final long evictNanos(final long timeoutMillis) { + static final long evictNanos(final @Nullable Duration timeout) { long nanos= System.nanoTime(); - if (timeoutMillis > 0) { - nanos+= timeoutMillis * 1_000_000L; + if (timeout != null && !timeout.isNegative()) { + nanos+= timeout.toNanos(); } return safeNanos(nanos); } @@ -76,8 +78,8 @@ } @Override - public long getCreationTime() { - return this.p.getCreateTime(); + public Instant getCreationTime() { + return this.p.getCreateInstant(); } @Override @@ -86,8 +88,8 @@ } @Override - public long getLastestAllocationDuration() { - return this.p.getActiveTimeMillis(); + public @Nullable Duration getLastestAllocationDuration() { + return this.p.getActiveDuration(); } @Override @@ -109,7 +111,8 @@ } @Override - public long getStateTime() { + @SuppressWarnings("null") + public Instant getStateTime() { switch (getState()) { case DISPOSED: return getShutdownTime(); @@ -143,8 +146,8 @@ } @Override - public void evict(final long timeout) { - doEvict(evictNanos(timeout), timeout == 0); + public void evict(final @Nullable Duration timeout) { + doEvict(evictNanos(timeout), timeout == null); } void doEvict(final long nanos, final boolean direct) {
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeObject.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeObject.java index 1a83fdd..c708e90 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeObject.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/APool2NodeObject.java
@@ -14,11 +14,13 @@ package org.eclipse.statet.internal.rj.servi; -import java.util.concurrent.TimeUnit; +import java.time.Duration; +import java.time.Instant; import org.apache.commons.pool2.impl.DefaultPooledObject; import org.eclipse.statet.jcommons.lang.NonNullByDefault; +import org.eclipse.statet.jcommons.lang.Nullable; @NonNullByDefault @@ -28,12 +30,12 @@ private volatile long lastAllocatedBeginNanos; private volatile long lastAllocatedEndNanos; - private volatile long stateTime; + private volatile Instant stateTime; public APool2NodeObject(final APool2NodeHandler object) { super(object); - this.stateTime= getCreateTime(); + this.stateTime= getCreateInstant(); } @@ -41,7 +43,7 @@ public synchronized boolean allocate() { if (super.allocate()) { this.lastAllocatedBeginNanos= System.nanoTime(); - this.stateTime= System.currentTimeMillis(); + this.stateTime= Instant.now(); return true; } return false; @@ -56,7 +58,7 @@ this.lastAllocatedEndNanos= System.nanoTime(); //$FALL-THROUGH$ default: - this.stateTime= System.currentTimeMillis(); + this.stateTime= Instant.now(); super.markReturning(); return; } @@ -71,7 +73,7 @@ this.lastAllocatedEndNanos= System.nanoTime(); //$FALL-THROUGH$ case RETURNING: - this.stateTime= System.currentTimeMillis(); + this.stateTime= Instant.now(); return super.deallocate(); default: return false; @@ -87,21 +89,21 @@ this.lastAllocatedEndNanos= System.nanoTime(); //$FALL-THROUGH$ default: - this.stateTime= System.currentTimeMillis(); + this.stateTime= Instant.now(); super.invalidate(); return; } } - public long getStateTime() { + public Instant getStateTime() { return this.stateTime; } @Override - public long getActiveTimeMillis() { + public @Nullable Duration getActiveDuration() { if (getBorrowedCount() <= 0) { - return -1; + return null; } final long end= this.lastAllocatedEndNanos; final long begin= this.lastAllocatedBeginNanos; @@ -109,7 +111,13 @@ if (t < 0) { t= System.nanoTime() - begin; } - return TimeUnit.NANOSECONDS.toMillis(t); + return Duration.ofNanos(t); + } + + @Override + public long getActiveTimeMillis() { + final var duration= getActiveDuration(); + return (duration != null) ? duration.toMillis() : -1; } }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNode.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNode.java index 09856f4..a5d4482 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNode.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNode.java
@@ -17,7 +17,8 @@ import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; import java.lang.management.ManagementFactory; -import java.util.Date; +import java.time.Duration; +import java.time.Instant; import javax.management.JMException; import javax.management.ObjectName; @@ -43,7 +44,7 @@ private final PoolServer server; private final PoolNodeObject nodeObj; private final RMIAddress address; - private final Date creationTime; + private final Instant creationTime; private @Nullable ObjectName jmName; @@ -53,7 +54,7 @@ this.nodeObj= nodeObj; final NodeHandler nodeHandler= nonNullAssert(this.nodeObj.getNodeHandler()); this.address= nonNullAssert(nodeHandler.getAddress()); - this.creationTime= new Date(this.nodeObj.getCreationTime()); + this.creationTime= this.nodeObj.getCreationTime(); } @@ -78,13 +79,13 @@ } @Override - public Date getCreationTime() { + public Instant getCreationTime() { return this.creationTime; } @Override public NodeStateMX getState() { - final PoolNodeItem item= new PoolNodeItem(this.nodeObj, System.currentTimeMillis()); + final PoolNodeItem item= new PoolNodeItem(this.nodeObj, Instant.now()); return new MXNodeState(item); } @@ -125,12 +126,12 @@ if (timeoutMillis < 0) { throw new OperationsException("Invalid parameter 'timeoutMillis' >= 0."); } - this.nodeObj.evict(timeoutMillis); + this.nodeObj.evict(Duration.ofMillis(timeoutMillis)); } @Override public void kill() throws OperationsException { - this.nodeObj.evict(0); + this.nodeObj.evict(null); } }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeConfig.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeConfig.java index 86e195a..2eedbe9 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeConfig.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeConfig.java
@@ -17,6 +17,7 @@ import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; import java.lang.management.ManagementFactory; +import java.time.Duration; import java.util.Map; import javax.management.JMException; @@ -74,6 +75,19 @@ @Override + public long getStartStopTimeoutMillis() { + final var timeout= getStartStopTimeout(); + return (timeout != null) ? timeout.toMillis() : -1; + } + + @Override + public void setStartStopTimeoutMillis(final long milliseconds) { + final var duration= (milliseconds != -1) ? Duration.ofMillis(milliseconds) : null; + setStartStopTimeout(duration); + } + + + @Override public void apply() throws OperationsException { synchronized (this) { MXUtils.validate(this);
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeState.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeState.java index 979e62e..91a28b0 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeState.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXNodeState.java
@@ -14,6 +14,7 @@ package org.eclipse.statet.internal.rj.servi; +import java.time.Instant; import java.util.Date; import org.eclipse.statet.jcommons.lang.NonNullByDefault; @@ -31,15 +32,15 @@ private final PoolNodeItem item; - private final Date creationTime; - private final Date stateTime; + private final Instant creationTime; + private final Instant stateTime; public MXNodeState(final PoolNodeItem item) { this.item= item; - this.creationTime= new Date(this.item.getCreationTime()); - this.stateTime= new Date(this.item.getStateTime()); + this.creationTime= this.item.getCreationTime(); + this.stateTime= this.item.getStateTime(); } @@ -50,7 +51,7 @@ @Override public Date getStateBeginTime() { - return this.stateTime; + return Date.from(this.stateTime); } @Override @@ -61,7 +62,7 @@ @Override public Date getCreationTime() { - return this.creationTime; + return Date.from(this.creationTime); } @Override @@ -70,8 +71,9 @@ } @Override - public long getUsageDuration() { - return this.item.getUsageDuration(); + public long getUsageDurationMillis() { + final var duration= this.item.getUsageDuration(); + return (duration != null) ? duration.toMillis() : -1; } @Override
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolConfig.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolConfig.java index 8de2b06..50c1a8b 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolConfig.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolConfig.java
@@ -17,6 +17,7 @@ import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; import java.lang.management.ManagementFactory; +import java.time.Duration; import javax.management.JMException; import javax.management.ObjectName; @@ -88,4 +89,40 @@ MXUtils.save(this, this.server.getRJContext()); } + + @Override + public long getAutoEvictionMinIdleTimeMillis() { + final var duration= getAutoEvictionMinIdleTime(); + return duration.toMillis(); + } + + @Override + public void setAutoEvictionMinIdleTimeMillis(final long milliseconds) { + setAutoEvictionMinIdleTime(Duration.ofMillis(milliseconds)); + } + + @Override + public long getAllocationTimeoutMillis() { + final var duration= getAllocationTimeout(); + return (duration != null) ? duration.toMillis() : -1; + } + + @Override + public void setAllocationTimeoutMillis(final long milliseconds) { + final var duration= (milliseconds != -1) ? Duration.ofMillis(milliseconds) : null; + setAllocationTimeout(duration); + } + + @Override + public long getEvictionTimeoutMillis() { + final var duration= getEvictionTimeout(); + return duration.toMillis(); + } + + @Override + public void setEvictionTimeoutMillis(final long milliseconds) { + setEvictionTimeout(Duration.ofMillis(milliseconds)); + } + + }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolStatus.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolStatus.java index c700dfd..0e7591a 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolStatus.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/internal/rj/servi/MXPoolStatus.java
@@ -17,6 +17,7 @@ import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit; import java.lang.management.ManagementFactory; +import java.time.Instant; import java.util.Date; import javax.management.JMException; @@ -38,7 +39,7 @@ private @Nullable ObjectName jmName; - private Date time= nonNullLateInit(); // ::refresh + private Instant time= nonNullLateInit(); // ::refresh public MXPoolStatus(final PoolServer server) { @@ -63,9 +64,9 @@ } protected synchronized void refresh() { - final long stamp= System.currentTimeMillis(); + final Instant stamp= Instant.now(); refresh(this.server.getManager(), stamp); - this.time= new Date(stamp); + this.time= stamp; } @@ -77,7 +78,7 @@ @Override public synchronized Date getStatusTime() { - return this.time; + return Date.from(this.time); }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeConfigMXBean.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeConfigMXBean.java index e704ba5..d98a43e 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeConfigMXBean.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeConfigMXBean.java
@@ -55,9 +55,9 @@ String getRStartupSnippet(); void setRStartupSnippet(@Nullable String code); - @DisplayName("Timeout when starting/stopping node (millis)") - long getStartStopTimeout(); - void setStartStopTimeout(long milliseconds); + @DisplayName("Timeout when starting/stopping node (millisec)") + long getStartStopTimeoutMillis(); + void setStartStopTimeoutMillis(long milliseconds); @DisplayName("Enable debug console") boolean getEnableConsole();
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeMXBean.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeMXBean.java index e33a78c..119d34b 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeMXBean.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeMXBean.java
@@ -14,7 +14,7 @@ package org.eclipse.statet.rj.servi.jmx; -import java.util.Date; +import java.time.Instant; import javax.management.OperationsException; @@ -26,7 +26,12 @@ String getId(); - Date getCreationTime(); + + /** + * @since 4.5 + */ + Instant getCreationTime(); + NodeStateMX getState(); @@ -36,9 +41,9 @@ @DisplayName("Stop using the default timeout") void stop() throws OperationsException; - @DisplayName("Stop using given timeout") + @DisplayName("Stop using given timeout (millisec)") void stop(long timeoutMillis) throws OperationsException; - @DisplayName("Stop using timeout 0") + @DisplayName("Stop directly") void kill() throws OperationsException; }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeStateMX.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeStateMX.java index 2f4d535..399d46d 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeStateMX.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/NodeStateMX.java
@@ -28,15 +28,18 @@ Date getCreationTime(); + PoolNodeState getState(); Date getStateBeginTime(); @Nullable String getCurrentClientLabel(); + long getUsageCount(); - long getUsageDuration(); + long getUsageDurationMillis(); + @Nullable String getRMIAddress();
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/PoolConfigMXBean.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/PoolConfigMXBean.java index 16980a0..b6ab0e1 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/PoolConfigMXBean.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/jmx/PoolConfigMXBean.java
@@ -24,32 +24,32 @@ @DisplayName("Max total nodes (count)") - int getMaxUsageCount(); - void setMaxUsageCount(int count); - - @DisplayName("Min idle nodes (count)") - long getMaxWaitTime(); - void setMaxWaitTime(long milliseconds); - - @DisplayName("Max idle nodes (count)") - long getMinIdleTime(); - void setMinIdleTime(long milliseconds); - - @DisplayName("Min node idle time (millisec)") - int getMaxIdleCount(); - void setMaxIdleCount(int count); - - @DisplayName("Max wait time (millisec)") - int getMinIdleCount(); - void setMinIdleCount(int count); - - @DisplayName("Max node reuse (count)") int getMaxTotalCount(); void setMaxTotalCount(int count); + @DisplayName("Max idle nodes (count)") + int getMaxIdleCount(); + void setMaxIdleCount(int count); + + @DisplayName("Min idle nodes (count)") + int getMinIdleCount(); + void setMinIdleCount(int count); + + @DisplayName("Max reuse of node (count)") + int getMaxUsageCount(); + void setMaxUsageCount(int count); + + @DisplayName("Min idle duration of node before automatic eviction (millisec)") + long getAutoEvictionMinIdleTimeMillis(); + void setAutoEvictionMinIdleTimeMillis(long milliseconds); + + @DisplayName("Timeout when requesting node (millisec)") + long getAllocationTimeoutMillis(); + void setAllocationTimeoutMillis(long milliseconds); + @DisplayName("Timeout when evicting node in use (millisec)") - long getEvictionTimeout(); - void setEvictionTimeout(long milliseconds); + long getEvictionTimeoutMillis(); + void setEvictionTimeoutMillis(long milliseconds); @DisplayName("Apply the current configuration")
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolConfig.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolConfig.java index 2931e6c..f4483a9 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolConfig.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolConfig.java
@@ -14,6 +14,11 @@ package org.eclipse.statet.rj.servi.pool; +import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; + +import static org.eclipse.statet.internal.rj.servi.Utils.isNegative; + +import java.time.Duration; import java.util.Collection; import java.util.Properties; @@ -57,28 +62,28 @@ */ public static final String EVICT_TIMEOUT_ID= "eviction_timeout.millis"; - private static final long EVICT_TIMEOUT_DEFAULT= 30*MINUTES; + private static final Duration EVICT_TIMEOUT_DEFAULT= Duration.ofMinutes(30); private int maxTotalCount; private int minIdleCount; private int maxIdleCount; - private long minIdleTime; - private long maxWaitTime; + private Duration autoEvictionMinIdleTime; private int maxUsageCount; - private long evictTimeout; + private @Nullable Duration allocationTimeout; + private Duration evictionTimeout; public PoolConfig() { this.maxTotalCount= 20; this.minIdleCount= 1; this.maxIdleCount= 10; - this.minIdleTime= 10*MINUTES; - this.maxWaitTime= 3*SECONDS; + this.autoEvictionMinIdleTime= Duration.ofMinutes(10); this.maxUsageCount= 1000; + this.allocationTimeout= Duration.ofSeconds(3); - this.evictTimeout= EVICT_TIMEOUT_DEFAULT; + this.evictionTimeout= EVICT_TIMEOUT_DEFAULT; } public PoolConfig(final PoolConfig config) { @@ -98,23 +103,29 @@ this.maxTotalCount= templ.maxTotalCount; this.minIdleCount= templ.minIdleCount; this.maxIdleCount= templ.maxIdleCount; - this.minIdleTime= templ.minIdleTime; - this.maxWaitTime= templ.maxWaitTime; + this.autoEvictionMinIdleTime= templ.autoEvictionMinIdleTime; + this.allocationTimeout= templ.allocationTimeout; this.maxUsageCount= templ.maxUsageCount; - this.evictTimeout= templ.evictTimeout; + this.evictionTimeout= templ.evictionTimeout; } @Override public synchronized void load(final Properties map) { - this.maxTotalCount= Integer.parseInt(map.getProperty(MAX_TOTAL_COUNT_ID)); - this.minIdleCount= Integer.parseInt(map.getProperty(MIN_IDLE_COUNT_ID)); - this.maxIdleCount= Integer.parseInt(map.getProperty(MAX_IDLE_COUNT_ID)); - this.minIdleTime= Long.parseLong(Utils.getProperty(map, MIN_IDLE_MILLIS_ID, MIN_IDLE_TIME_ID)); - this.maxWaitTime= Long.parseLong(Utils.getProperty(map, MAX_WAIT_MILLIS_ID, MAX_WAIT_TIME_ID)); - this.maxUsageCount= Integer.parseInt(map.getProperty(MAX_USAGE_COUNT_ID)); - { final String s= map.getProperty(EVICT_TIMEOUT_ID); - this.evictTimeout= (s != null) ? Long.parseLong(s) : EVICT_TIMEOUT_DEFAULT; - } + this.maxTotalCount= Integer.parseInt( + map.getProperty(MAX_TOTAL_COUNT_ID) ); + this.minIdleCount= Integer.parseInt( + map.getProperty(MIN_IDLE_COUNT_ID) ); + this.maxIdleCount= Integer.parseInt( + map.getProperty(MAX_IDLE_COUNT_ID) ); + this.autoEvictionMinIdleTime= Utils.parseDuration( + Utils.getProperty(map, MIN_IDLE_MILLIS_ID, MIN_IDLE_TIME_ID) ); + this.allocationTimeout= Utils.parseNullableDuration( + Utils.getProperty(map, MAX_WAIT_MILLIS_ID, MAX_WAIT_TIME_ID) ); + this.maxUsageCount= Integer.parseInt( + map.getProperty(MAX_USAGE_COUNT_ID) ); + this.evictionTimeout= Utils.parseDuration( + map.getProperty(EVICT_TIMEOUT_ID), + EVICT_TIMEOUT_DEFAULT ); } @Override @@ -122,10 +133,10 @@ map.setProperty(MAX_TOTAL_COUNT_ID, Integer.toString(this.maxTotalCount)); map.setProperty(MIN_IDLE_COUNT_ID, Integer.toString(this.minIdleCount)); map.setProperty(MAX_IDLE_COUNT_ID, Integer.toString(this.maxIdleCount)); - map.setProperty(MIN_IDLE_MILLIS_ID, Long.toString(this.minIdleTime)); - map.setProperty(MAX_WAIT_MILLIS_ID, Long.toString(this.maxWaitTime)); + map.setProperty(MIN_IDLE_MILLIS_ID, Utils.serDuration(this.autoEvictionMinIdleTime)); + map.setProperty(MAX_WAIT_MILLIS_ID, Utils.serNullableDuration(this.allocationTimeout)); map.setProperty(MAX_USAGE_COUNT_ID, Integer.toString(this.maxUsageCount)); - map.setProperty(EVICT_TIMEOUT_ID, Long.toString(this.evictTimeout)); + map.setProperty(EVICT_TIMEOUT_ID, Utils.serDuration(this.evictionTimeout)); } public synchronized int getMaxTotalCount() { @@ -152,52 +163,62 @@ this.maxIdleCount= count; } - public synchronized long getMinIdleTime() { - return this.minIdleTime; + /** + * @since 4.5 + */ + public synchronized Duration getAutoEvictionMinIdleTime() { + return this.autoEvictionMinIdleTime; } - public synchronized void setMinIdleTime(final long milliseconds) { - this.minIdleTime= milliseconds; - } - - public synchronized void setMaxWaitTime(final long milliseconds) { - this.maxWaitTime= milliseconds; - } - - public synchronized long getMaxWaitTime() { - return this.maxWaitTime; - } - - public synchronized void setMaxUsageCount(final int count) { - this.maxUsageCount= count; + /** + * @since 4.5 + */ + public synchronized void setAutoEvictionMinIdleTime(final Duration duration) { + this.autoEvictionMinIdleTime= nonNullAssert(duration); } public synchronized int getMaxUsageCount() { return this.maxUsageCount; } + public synchronized void setMaxUsageCount(final int count) { + this.maxUsageCount= count; + } + + /** + * @since 4.5 + */ + public synchronized @Nullable Duration getAllocationTimeout() { + return this.allocationTimeout; + } + + /** + * @since 4.5 + */ + public synchronized void setAllocationTimeout(final @Nullable Duration timeout) { + this.allocationTimeout= timeout; + } /** * Returns the timeout when evicing lent pool items * - * @return the timeout in milliseconds + * @return the timeout * - * @since 2.0 + * @since 4.5 */ - public synchronized long getEvictionTimeout() { - return this.evictTimeout; + public synchronized Duration getEvictionTimeout() { + return this.evictionTimeout; } /** * Sets the timeout when evicing lent pool items * - * @param milliseconds the timeout in milliseconds + * @param duration the timeout * - * @since 2.0 + * @since 4.5 */ - - public synchronized void setEvictionTimeout(final long milliseconds) { - this.evictTimeout= milliseconds; + public synchronized void setEvictionTimeout(final Duration duration) { + this.evictionTimeout= nonNullAssert(duration); } @@ -229,15 +250,15 @@ } valid= false; } - if (this.minIdleTime < 0L) { + if (this.autoEvictionMinIdleTime.isNegative()) { if (messages != null) { messages.add(new ValidationMessage(MIN_IDLE_MILLIS_ID, "Value must be >= 0")); } valid= false; } - if (this.maxWaitTime < 0L && this.maxUsageCount != -1) { + if (this.maxUsageCount != -1 && isNegative(this.allocationTimeout)) { if (messages != null) { - messages.add(new ValidationMessage(MAX_WAIT_MILLIS_ID, "Value must be >= 0 or == -1 (infinite)")); + messages.add(new ValidationMessage(MAX_WAIT_MILLIS_ID, "Value must be >= 0 or unset/== -1 (infinite)")); } valid= false; } @@ -248,7 +269,7 @@ valid= false; } - if (this.evictTimeout < 0) { + if (this.evictionTimeout.isNegative()) { if (messages != null) { messages.add(new ValidationMessage(EVICT_TIMEOUT_ID, "Value must be >= 0")); }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeItem.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeItem.java index c79357f..1278c12 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeItem.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeItem.java
@@ -14,6 +14,9 @@ package org.eclipse.statet.rj.servi.pool; +import java.time.Duration; +import java.time.Instant; + import org.eclipse.statet.jcommons.lang.NonNullByDefault; import org.eclipse.statet.jcommons.lang.Nullable; import org.eclipse.statet.jcommons.rmi.RMIAddress; @@ -28,19 +31,19 @@ private final PoolNodeObject nodeObj; - private long creationTime; + private Instant creationTime; private PoolNodeState state; - private long stateTime; + private Instant stateTime; private long usageCount; - private long usageDuration; + private @Nullable Duration usageDuration; private @Nullable RMIAddress address; private @Nullable String clientLabel; - public PoolNodeItem(final PoolNodeObject nodeObj, final long stamp) { + public PoolNodeItem(final PoolNodeObject nodeObj, final Instant stamp) { synchronized(nodeObj) { this.nodeObj= nodeObj; @@ -58,7 +61,10 @@ } - public long getCreationTime() { + /** + * @since 4.5 + */ + public Instant getCreationTime() { return this.creationTime; } @@ -66,7 +72,10 @@ return this.state; } - public long getStateTime() { + /** + * @since 4.5 + */ + public Instant getStateTime() { return this.stateTime; } @@ -78,7 +87,10 @@ return this.usageCount; } - public long getUsageDuration() { + /** + * @since 4.5 + */ + public @Nullable Duration getUsageDuration() { return this.usageDuration; } @@ -117,13 +129,13 @@ * * The specified timeout is used when the node is in use. * - * @param timeoutMillis the timeout in milliseconds + * @param timeout the timeout * - * @since 2.0 + * @since 4.5 */ - public void evict(final long timeoutMillis) { + public void evict(final @Nullable Duration timeout) { if (this.nodeObj != null) { - this.nodeObj.evict(timeoutMillis); + this.nodeObj.evict(timeout); } }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeObject.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeObject.java index 5ad5b75..a7e04bc 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeObject.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolNodeObject.java
@@ -14,6 +14,9 @@ package org.eclipse.statet.rj.servi.pool; +import java.time.Duration; +import java.time.Instant; + import org.eclipse.statet.jcommons.lang.NonNullByDefault; import org.eclipse.statet.jcommons.lang.Nullable; @@ -30,8 +33,10 @@ * Returns the time of the creation of the node. * * @return the time in milliseconds (as specified by {@link System#currentTimeMillis()}) + * + * @since 4.5 */ - long getCreationTime(); + Instant getCreationTime(); /** * Returns the count of allocation of this node. @@ -49,9 +54,11 @@ * If the node is currently allocated, it is the duration of the current allocation at this * time. * - * @return the duration in milliseconds, or {@code -1} if not available + * @return the duration, or {@code null} if not available + * + * @since 4.5 */ - long getLastestAllocationDuration(); + @Nullable Duration getLastestAllocationDuration(); /** * Returns the current state. @@ -60,11 +67,27 @@ */ PoolNodeState getState(); - long getStateTime(); + /** + * @since 4.5 + */ + Instant getStateTime(); @Nullable String getClientLabel(); - void evict(long timeoutMillis); + /** + * Marks this node for eviction. + * + * @param timeout the timeout for eviction, or {@code null} for direct eviction in current + * thread + * + * @since 4.5 + */ + void evict(@Nullable Duration timeout); + + @Deprecated(since= "4.5") + default void evict(final long timeoutMillis) { + evict((timeoutMillis == 0) ? null : Duration.ofMillis(timeoutMillis)); + } }
diff --git a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolStatus.java b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolStatus.java index 41eef1d..1abb59a 100644 --- a/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolStatus.java +++ b/servi/org.eclipse.statet.rj.servi/srcServiPool/org/eclipse/statet/rj/servi/pool/PoolStatus.java
@@ -17,6 +17,7 @@ import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -43,7 +44,7 @@ protected final PoolServer server; /*-- init in ::check() --*/ - private long stamp; + private Instant stamp= nonNullLateInit(); private RServiPoolManager.Counter counter= nonNullLateInit(); private List<N> nodeStates= nonNullLateInit(); @@ -53,7 +54,10 @@ } - protected long getStatusStamp() { + /** + * @since 4.5 + */ + protected Instant getStatusStamp() { return this.stamp; } @@ -98,7 +102,7 @@ } - protected void refresh(final @Nullable RServiPoolManager manager, final long stamp) { + protected void refresh(final @Nullable RServiPoolManager manager, final Instant stamp) { final List<N> list; RServiPoolManager.Counter counter; @@ -136,7 +140,7 @@ this.nodeStates= list; } - protected PoolNodeItem createPoolItem(final PoolNodeObject node, final long stamp) { + protected PoolNodeItem createPoolItem(final PoolNodeObject node, final Instant stamp) { return new PoolNodeItem(node, stamp); }