From 01dc63f774c931f92f7c6e28c406b0f478ac4a9f Mon Sep 17 00:00:00 2001
From: "elena.parovyshnaya"
Date: Thu, 5 Dec 2019 15:56:11 +0300
Subject: [PATCH] # 553807 - revise permission observatory API
- Observatory is renamed to Pool
- GuardedObservatory is renamed to Observatory
- schedule semantics is formed to a separate class
- which is, in turn, covered with tests
Signed-off-by: elena.parovyshnaya
---
.../META-INF/MANIFEST.MF | 2 +-
.../permission/BasePermissionObservatory.java | 13 +--
.../base/permission/LimitedPermission.java | 4 +-
.../permission/PermissionObservatory.java | 4 +-
.../permission/observatory/CheckSchedule.java | 82 ++++++++++++++
.../base/permission/observatory/Guard.java | 8 +-
.../observatory/GuardedObservatory.java | 92 ----------------
.../permission/observatory/Observatory.java | 101 ++++++++++++++----
.../base/permission/observatory/Pool.java | 43 ++++++++
.../access/EquinoxPermissionObservatory.java | 5 +-
.../observatory/CheckScheduleTest.java | 39 +++++++
.../observatory/ObservatoryTest.java | 14 ++-
12 files changed, 276 insertions(+), 131 deletions(-)
create mode 100644 bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckSchedule.java
delete mode 100644 bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/GuardedObservatory.java
create mode 100644 bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Pool.java
create mode 100644 tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckScheduleTest.java
diff --git a/bundles/org.eclipse.passage.lic.base/META-INF/MANIFEST.MF b/bundles/org.eclipse.passage.lic.base/META-INF/MANIFEST.MF
index ab19a27af..d74ed2cbe 100644
--- a/bundles/org.eclipse.passage.lic.base/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.passage.lic.base/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Automatic-Module-Name: org.eclipse.passage.lic.api.base
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.passage.lic.base
-Bundle-Version: 0.6.0.qualifier
+Bundle-Version: 0.6.1.qualifier
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
Bundle-Copyright: %Bundle-Copyright
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/BasePermissionObservatory.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/BasePermissionObservatory.java
index e20436344..8f6aa21f7 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/BasePermissionObservatory.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/BasePermissionObservatory.java
@@ -17,24 +17,25 @@
import java.util.stream.StreamSupport;
import org.eclipse.passage.lic.api.access.FeaturePermission;
-import org.eclipse.passage.lic.internal.base.permission.observatory.GuardedObservatory;
+import org.eclipse.passage.lic.internal.base.permission.observatory.CheckSchedule;
+import org.eclipse.passage.lic.internal.base.permission.observatory.Observatory;
/**
*
* Base implementation for {@linkplain PermissionObservatory} component.
*
*
- * Covers {@linkplain GuardedObservatory} tuned for permission tracking and is
- * it's representation for the domain specific environment.
+ * Covers {@linkplain Observatory} tuned for permission tracking and is it's
+ * representation for the domain specific environment.
*
*
* @since 0.6
*/
public final class BasePermissionObservatory implements PermissionObservatory {
- private final GuardedObservatory observatory;
+ private final Observatory observatory;
- public BasePermissionObservatory(int seconds, Consumer> farewell) {
- this.observatory = new GuardedObservatory(seconds, farewell);
+ public BasePermissionObservatory(CheckSchedule schedule, Consumer> farewell) {
+ this.observatory = new Observatory(schedule, farewell);
}
public void watch(Iterable permissions) {
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/LimitedPermission.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/LimitedPermission.java
index 98db467ae..47e6b01de 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/LimitedPermission.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/LimitedPermission.java
@@ -15,12 +15,12 @@
import java.util.Date;
import org.eclipse.passage.lic.api.access.FeaturePermission;
-import org.eclipse.passage.lic.internal.base.permission.observatory.GuardedObservatory;
+import org.eclipse.passage.lic.internal.base.permission.observatory.Observatory;
import org.eclipse.passage.lic.internal.base.permission.observatory.Limited;
/**
* Adapter for {@linkplain FeaturePermission} to implement {@linkplain Limited}
- * interface to be properly tracked by {@linkplain GuardedObservatory}
+ * interface to be properly tracked by {@linkplain Observatory}
*
* @since 0.6
*/
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/PermissionObservatory.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/PermissionObservatory.java
index 341a97373..11d7eb7f1 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/PermissionObservatory.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/PermissionObservatory.java
@@ -12,10 +12,10 @@
*******************************************************************************/
package org.eclipse.passage.lic.internal.base.permission;
-import org.eclipse.passage.lic.internal.base.permission.observatory.GuardedObservatory;
+import org.eclipse.passage.lic.internal.base.permission.observatory.Observatory;
/**
- * Marker interface for a component that holds {@linkplain GuardedObservatory}
+ * Marker interface for a component that holds {@linkplain Observatory}
* for permission tracking.
*
* @since 0.6
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckSchedule.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckSchedule.java
new file mode 100644
index 000000000..7eb6169a1
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckSchedule.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2019 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.internal.base.permission.observatory;
+
+import java.time.temporal.ChronoUnit;
+
+/**
+ *
+ * Schedule for observatory checks.
+ *
+ *
+ *
+ * Been defined for 5 minutes, causes the observatory to check for new
+ * expired entries each 5 minutes (or so).
+ *
+ *
+ * @since 0.6
+ */
+public class CheckSchedule {
+
+ private final int amount;
+ private final ChronoUnit unit;
+
+ /**
+ *
+ * Use desired units to define the most suitable check schedule.
+ *
+ *
+ *
+ * For example, {@code new CheckSchedule(2, ChronoUnit.DAYS)}, been given to an
+ * observatory, will cause the closest expiration check to happen only in two
+ * days since the observatory opening.
+ *
+ *
+ * @param amount number of units
+ * @unit {@linkplain ChronoUnit} constant to measure {@code amount}
+ * @since 0.6
+ */
+ public CheckSchedule(int amount, ChronoUnit unit) {
+ this.amount = amount;
+ this.unit = unit;
+ }
+
+ /**
+ * Default schedules are measured in minutes.
+ *
+ * @param minutes number of minutes
+ * @since 0.6
+ */
+ public CheckSchedule(int minutes) {
+ this(minutes, ChronoUnit.MINUTES);
+ }
+
+ /**
+ * Default schedule is 10 minutes.
+ *
+ * @since 0.6
+ */
+ public CheckSchedule() {
+ this(10, ChronoUnit.MINUTES);
+ }
+
+ /**
+ * Reports the scheduled period duration in seconds.
+ *
+ * @since 0.6
+ */
+ public long seconds() {
+ return unit.getDuration().getSeconds() * amount;
+ }
+
+}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Guard.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Guard.java
index 7d47f670c..bd6cdaf56 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Guard.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Guard.java
@@ -19,8 +19,8 @@
final class Guard implements Runnable {
- private final int period;
- private final Observatory pool;
+ private final long period;
+ private final Pool pool;
private final Consumer> onExpire;
private final Executor executor;
@@ -28,8 +28,8 @@ final class Guard implements Runnable {
* @param onExpire never gets {@code null} or empty set. The callback is
* expected to complete shortly.
*/
- Guard(int seconds, Observatory pool, Consumer> onExpire) {
- this.period = seconds;
+ Guard(CheckSchedule schedule, Pool pool, Consumer> onExpire) {
+ this.period = schedule.seconds();
this.pool = pool;
this.onExpire = onExpire;
executor = Executors.newSingleThreadExecutor();
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/GuardedObservatory.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/GuardedObservatory.java
deleted file mode 100644
index 309dbbd3d..000000000
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/GuardedObservatory.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019 ArSysOp
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * ArSysOp - initial API and implementation
- *******************************************************************************/
-package org.eclipse.passage.lic.internal.base.permission.observatory;
-
-import java.util.Set;
-import java.util.function.Consumer;
-
-/**
- *
- * This observatory keeps an eye on any captured entry, that can say in a moment
- * of time whether it is expired already or not yet.
- *
- *
- *
- * Ones in a period of time the observatory checks all watched entries if they
- * are expired already. And for the ones who do, a configured action is called.
- *
- *
- *
- * An entry can be put under the observatoryControl and removed from it
- * preliminary, prior this is done by TTL.
- *
- *
- * @since 0.6
- */
-public final class GuardedObservatory {
- private final Observatory observatory;
- private final Guard guard;
-
- /**
- *
- * When the time comes and an entry expires, {@code farewell} action is called
- * for it.
- *
- *
- *
- * The observatory does the brushing checks each {@code schedule} seconds, so an
- * entry cannot be processed precisely in a moment it expires, but some time
- * like {@code schedule} seconds after.
- *
- *
- * @param schedule period (in seconds) between checks
- * @param farewell handler to be notified of expired entries. Is not intended to
- * work long. Never bothered for naught: never gets {@code null}
- * or empty set.
- * @since 0.6
- */
- public GuardedObservatory(int schedule, Consumer> farewell) {
- observatory = new Observatory();
- guard = new Guard(schedule, observatory, farewell);
- }
-
- /**
- * The observatory can accept entries to watch and dismiss them after, but
- * checks start only after it is open.
- *
- * @since 0.6
- */
- public void open() {
- new Thread(guard).start();
- }
-
- /**
- * Put a {@link Limited} entry under the observatory control.
- *
- * @since 0.6
- */
- public void watch(T limited) {
- observatory.watch(limited);
- }
-
- /**
- * Remove a {@link Limited} entry from the observatory control intentionally
- * prior it's expiration.
- *
- * @since 0.6
- */
- public void forget(T limited) {
- observatory.forget(limited);
- }
-
-}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Observatory.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Observatory.java
index 7d2b76c88..3add49d41 100644
--- a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Observatory.java
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Observatory.java
@@ -12,30 +12,95 @@
*******************************************************************************/
package org.eclipse.passage.lic.internal.base.permission.observatory;
-import java.util.HashSet;
import java.util.Set;
-import java.util.stream.Collectors;
+import java.util.function.Consumer;
-final class Observatory {
- private final Set watched = new HashSet<>();
+/**
+ *
+ * This observatory keeps an eye on any captured entry, that can say in a moment
+ * of time whether it is expired already or not yet.
+ *
+ *
+ *
+ * Ones in a period of time the observatory checks all watched entries if they
+ * are expired already. And for the ones who do, a configured action is called.
+ * Since this moment an expired entry in not watched anymore.
+ *
+ *
+ *
+ * There is no check on an observatory opening. The closest one takes place only
+ * after a scheduled period of time is over.
+ *
+ *
+ *
+ * An entry can be put under the observatory control and removed from it
+ * preliminary, prior this is done by TTL.
+ *
+ *
+ *
+ * To configure an observatory, you need only define
+ *
+ * - how often it will check expiration and
+ * - what will it do for expired entries
+ *
+ *
+ *
+ * @since 0.6
+ */
+public final class Observatory {
+ private final Pool pool;
+ private final Guard guard;
- void watch(T target) {
- synchronized (watched) {
- watched.add(target);
- }
+ /**
+ *
+ * When the time comes and an entry expires, {@code farewell} action is called
+ * for it.
+ *
+ *
+ *
+ * The observatory does the brushing checks each {@code schedule} seconds, so an
+ * entry cannot be processed precisely in a moment it expires, but some time
+ * like {@code schedule} seconds after.
+ *
+ *
+ * @param schedule period (in seconds) between checks
+ * @param farewell handler to be notified of expired entries. Is not intended to
+ * work long. Never bothered for naught: never gets {@code null}
+ * or empty set.
+ * @since 0.6
+ */
+ public Observatory(CheckSchedule schedule, Consumer> farewell) {
+ pool = new Pool();
+ guard = new Guard(schedule, pool, farewell);
}
- void forget(T target) {
- synchronized (watched) {
- watched.remove(target);
- }
+ /**
+ * The observatory can accept entries to watch and dismiss them after, but
+ * checks start only after it is open.
+ *
+ * @since 0.6
+ */
+ public void open() {
+ new Thread(guard).start();
}
- Expired popExpired() {
- synchronized (watched) {
- Set expired = watched.stream().filter(Limited::expired).collect(Collectors.toSet());
- watched.removeAll(expired);
- return new Expired(expired);
- }
+ /**
+ * Put a {@link Limited} entry under the observatory control.
+ *
+ * @since 0.6
+ */
+ public void watch(T limited) {
+ pool.watch(limited);
}
+
+ /**
+ * Remove a {@link Limited} entry from the observatory control intentionally
+ * prior it's expiration.
+ *
+ * @since 0.6
+ */
+ public void forget(T limited) {
+ pool.forget(limited);
+ }
+
}
diff --git a/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Pool.java b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Pool.java
new file mode 100644
index 000000000..bc3da3af7
--- /dev/null
+++ b/bundles/org.eclipse.passage.lic.base/src/org/eclipse/passage/lic/internal/base/permission/observatory/Pool.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2019 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.internal.base.permission.observatory;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+final class Pool {
+ private final Set watched = new HashSet<>();
+
+ void watch(T target) {
+ synchronized (watched) {
+ watched.add(target);
+ }
+ }
+
+ void forget(T target) {
+ synchronized (watched) {
+ watched.remove(target);
+ }
+ }
+
+ Expired popExpired() {
+ synchronized (watched) {
+ Set expired = watched.stream() //
+ .filter(Limited::expired)//
+ .collect(Collectors.toSet());
+ watched.removeAll(expired);
+ return new Expired(expired);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/access/EquinoxPermissionObservatory.java b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/access/EquinoxPermissionObservatory.java
index 2b4ee8d3d..da6bacd97 100644
--- a/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/access/EquinoxPermissionObservatory.java
+++ b/bundles/org.eclipse.passage.lic.equinox/src/org/eclipse/passage/lic/internal/equinox/access/EquinoxPermissionObservatory.java
@@ -14,6 +14,7 @@
import static org.eclipse.passage.lic.base.LicensingResults.createEvent;
+import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.Set;
@@ -24,6 +25,7 @@
import org.eclipse.passage.lic.internal.base.permission.BasePermissionObservatory;
import org.eclipse.passage.lic.internal.base.permission.LimitedPermission;
import org.eclipse.passage.lic.internal.base.permission.PermissionObservatory;
+import org.eclipse.passage.lic.internal.base.permission.observatory.CheckSchedule;
import org.eclipse.passage.lic.internal.equinox.EquinoxEvents;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -50,7 +52,8 @@ public final class EquinoxPermissionObservatory implements EventHandler, Permiss
@Activate
public void activate(Map config) {
int schedule = (Integer) config.get("observatory.schedule"); //$NON-NLS-1$
- observatory = new BasePermissionObservatory(schedule, this::fireExpiration);
+ observatory = new BasePermissionObservatory(new CheckSchedule(schedule, ChronoUnit.SECONDS),
+ this::fireExpiration);
observatory.open();
}
diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckScheduleTest.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckScheduleTest.java
new file mode 100644
index 000000000..5bea00077
--- /dev/null
+++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/CheckScheduleTest.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2019 ArSysOp
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * ArSysOp - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.passage.lic.internal.base.permission.observatory;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.temporal.ChronoUnit;
+
+import org.junit.Test;
+
+@SuppressWarnings("restriction")
+public class CheckScheduleTest {
+
+ @Test
+ public void testDefaultSchedule() {
+ assertEquals(10 * 60, new CheckSchedule().seconds());
+ }
+
+ @Test
+ public void testMinutesSchedule() {
+ assertEquals(5 * 60, new CheckSchedule(5).seconds());
+ }
+
+ @Test
+ public void testAlternativechedule() {
+ assertEquals(3 * 24 * 60 * 60, new CheckSchedule(3, ChronoUnit.DAYS).seconds());
+ }
+
+}
diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/ObservatoryTest.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/ObservatoryTest.java
index c7209faeb..5365759b4 100644
--- a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/ObservatoryTest.java
+++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/permission/observatory/ObservatoryTest.java
@@ -14,6 +14,7 @@
import static org.junit.Assert.fail;
+import java.time.temporal.ChronoUnit;
import java.util.Set;
import java.util.function.Consumer;
@@ -21,8 +22,8 @@
import org.junit.Test;
/**
- * Test suite for {@linkplain GuardedObservatory}, which mostly intended to keep
- * an eye on {@linkplain Limited} instances, given under it's watch and fire
+ * Test suite for {@linkplain Observatory}, which mostly intended to keep an eye
+ * on {@linkplain Limited} instances, given under it's watch and fire
* {@code expired} action when a {@linkplain Limited} expires.
*
* @since 0.6
@@ -46,7 +47,7 @@ public class ObservatoryTest {
@Test
public void twoSeconds() {
Countdown countdown = new Countdown(2);
- GuardedObservatory observatory = new GuardedObservatory(1, countdown);
+ Observatory observatory = new Observatory(buzy(), countdown);
observatory.open();
observatory.watch(new TimeLimited(1));
observatory.watch(new TimeLimited(1));
@@ -60,7 +61,7 @@ public void twoSeconds() {
@Test
public void forget() {
Countdown countdown = new Countdown(1); // watch two entries, but then forget one of them
- GuardedObservatory observatory = new GuardedObservatory(1, countdown);
+ Observatory observatory = new Observatory(buzy(), countdown);
observatory.open();
observatory.watch(new TimeLimited(1));
TimeLimited toBeForgotten = new TimeLimited(1);
@@ -86,7 +87,7 @@ public void guardIsHighlyReliable() {
private void testGuardReliability(Consumer> sabotage) {
Countdown countdown = new Countdown(4);
- GuardedObservatory observatory = new GuardedObservatory(1, countdown.andThen(sabotage));
+ Observatory observatory = new Observatory(buzy(), countdown.andThen(sabotage));
observatory.open();
observatory.watch(new TimeLimited(1));
observatory.watch(new TimeLimited(1));
@@ -118,6 +119,9 @@ private void assertCountdownIsComplete(Countdown countdown, int delay) {
fail("Some expired Limited are still active."); //$NON-NLS-1$
}
+ private CheckSchedule buzy() {
+ return new CheckSchedule(1, ChronoUnit.SECONDS);
+ }
// multithreaded usage
// failing in Limited::expire implementation
// negative schedule