|
|
@@ -6,9 +6,12 @@
|
|
|
*/
|
|
|
package net.ranides.assira.events;
|
|
|
|
|
|
+import java.util.Optional;
|
|
|
import java.util.concurrent.BlockingQueue;
|
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.function.Predicate;
|
|
|
+
|
|
|
import net.ranides.assira.annotations.Meta;
|
|
|
import net.ranides.assira.trace.LoggerUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
@@ -111,10 +114,10 @@ public abstract class EventLock<E extends Event> {
|
|
|
* minie podany czas.
|
|
|
* Zobacz opis klasy {@link EventLock} aby poznać szczegóły.
|
|
|
* @param timeout
|
|
|
- * @return oczekiwane zdarzenie
|
|
|
+ * @return oczekiwane zdarzenie lub {@code null}, jeśli minął {@code timeout}
|
|
|
* @throws InterruptedException
|
|
|
*/
|
|
|
- public abstract E waitForEvent(long timeout) throws InterruptedException;
|
|
|
+ public abstract Optional<E> waitForEvent(long timeout) throws InterruptedException;
|
|
|
|
|
|
/**
|
|
|
* Wersja oczekująca na zdarzenie konkretnego rodzaju. Zachowuje się identycznie
|
|
|
@@ -127,10 +130,12 @@ public abstract class EventLock<E extends Event> {
|
|
|
* </p>
|
|
|
* @param <T>
|
|
|
* @param event
|
|
|
- * @return oczekiwane zdarzenie lub {@code null}, jeśli minął {@code timeout}
|
|
|
+ * @return oczekiwane zdarzenie
|
|
|
* @throws InterruptedException
|
|
|
*/
|
|
|
- public abstract <T extends E> T waitForEvent(Class<T> event) throws InterruptedException;
|
|
|
+ public final <T extends E> T waitForEvent(Class<T> event) throws InterruptedException {
|
|
|
+ return event.cast(waitForEvent(event::isInstance));
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Wersja oczekująca na zdarzenie konkretnego rodzaju. Zachowuje się identycznie
|
|
|
@@ -147,7 +152,36 @@ public abstract class EventLock<E extends Event> {
|
|
|
* @return oczekiwane zdarzenie lub {@code null}, jeśli minął {@code timeout}
|
|
|
* @throws InterruptedException
|
|
|
*/
|
|
|
- public abstract <T extends E> T waitForEvent(Class<T> event, long timeout) throws InterruptedException;
|
|
|
+ public final <T extends E> Optional<T> waitForEvent(Class<T> event, long timeout) throws InterruptedException {
|
|
|
+ return waitForEvent(event::isInstance, timeout).map(event::cast);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Wersja oczekująca na zdarzenie spełniające warunek. Zachowuje się identycznie
|
|
|
+ * jak {@link #waitForEvent()}, z tą różnicą, że reaguje na mniejszy zakres
|
|
|
+ * zdarzeń - zawężony tylko do tych spełniających warunek.
|
|
|
+ * <p>
|
|
|
+ * Metoda przydatna szczególnie wtedy, gdy chcemy oczekiwać na zdarzenie z konkretnym correlation id.
|
|
|
+ * </p>
|
|
|
+ * @param condition
|
|
|
+ * @return oczekiwane zdarzenie
|
|
|
+ * @throws InterruptedException
|
|
|
+ */
|
|
|
+ public abstract E waitForEvent(Predicate<E> condition) throws InterruptedException;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Wersja oczekująca na zdarzenie spełniające warunek. Zachowuje się identycznie
|
|
|
+ * jak {@link #waitForEvent(long timeout)}, z tą różnicą, że reaguje na mniejszy zakres
|
|
|
+ * zdarzeń - zawężony tylko do tych spełniających warunek.
|
|
|
+ * <p>
|
|
|
+ * Metoda przydatna szczególnie wtedy, gdy chcemy oczekiwać na zdarzenie z konkretnym correlation id.
|
|
|
+ * </p>
|
|
|
+ * @param condition
|
|
|
+ * @param timeout
|
|
|
+ * @return oczekiwane zdarzenie lub {@code null}, jeśli minął {@code timeout}
|
|
|
+ * @throws InterruptedException
|
|
|
+ */
|
|
|
+ public abstract Optional<E> waitForEvent(Predicate<E> condition, long timeout) throws InterruptedException;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -266,7 +300,7 @@ public abstract class EventLock<E extends Event> {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public EE waitForEvent(long timeout) throws InterruptedException {
|
|
|
+ public Optional<EE> waitForEvent(long timeout) throws InterruptedException {
|
|
|
long rem = TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
|
|
|
long end = System.nanoTime()+ rem;
|
|
|
synchronized (this) {
|
|
|
@@ -276,32 +310,32 @@ public abstract class EventLock<E extends Event> {
|
|
|
}
|
|
|
EE result = hit;
|
|
|
hit = null;
|
|
|
- return result;
|
|
|
+ return Optional.ofNullable(result);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event) throws InterruptedException {
|
|
|
+ public EE waitForEvent(Predicate<EE> condition) throws InterruptedException {
|
|
|
synchronized (this) {
|
|
|
- while( !event.isInstance(hit) ) { this.wait(); }
|
|
|
- Event ret = hit;
|
|
|
+ while(hit==null || condition.test(hit) ) { this.wait(); }
|
|
|
+ EE ret = hit;
|
|
|
hit = null;
|
|
|
- return event.cast(ret);
|
|
|
+ return ret;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event, long timeout) throws InterruptedException {
|
|
|
+ public Optional<EE> waitForEvent(Predicate<EE> condition, long timeout) throws InterruptedException {
|
|
|
long rem = TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
|
|
|
long end = System.nanoTime()+ rem;
|
|
|
synchronized (this) {
|
|
|
- while( !event.isInstance(hit) && rem>0) {
|
|
|
+ while ((hit==null || !condition.test(hit)) && rem>0) {
|
|
|
this.waitNS(rem);
|
|
|
rem = end - System.nanoTime();
|
|
|
}
|
|
|
EE ret = hit;
|
|
|
hit = null;
|
|
|
- return event.cast(ret);
|
|
|
+ return Optional.ofNullable(ret);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -341,32 +375,32 @@ public abstract class EventLock<E extends Event> {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public EE waitForEvent(long timeout) throws InterruptedException {
|
|
|
- return events.poll(timeout, TimeUnit.MILLISECONDS);
|
|
|
+ public Optional<EE> waitForEvent(long timeout) throws InterruptedException {
|
|
|
+ return Optional.ofNullable(events.poll(timeout, TimeUnit.MILLISECONDS));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event) throws InterruptedException {
|
|
|
+ public EE waitForEvent(Predicate<EE> condition) throws InterruptedException {
|
|
|
while(true) {
|
|
|
EE recent = events.take();
|
|
|
- if( event.isInstance(recent) ) {
|
|
|
- return event.cast(recent);
|
|
|
+ if( condition.test(recent) ) {
|
|
|
+ return recent;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event, long timeout) throws InterruptedException {
|
|
|
+ public Optional<EE> waitForEvent(Predicate<EE> condition, long timeout) throws InterruptedException {
|
|
|
long rem = TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
|
|
|
long end = System.nanoTime()+ rem;
|
|
|
while(rem > 0) {
|
|
|
EE recent = events.poll(rem, TimeUnit.NANOSECONDS);
|
|
|
- if( event.isInstance(recent) ) {
|
|
|
- return event.cast(recent);
|
|
|
+ if( recent !=null && condition.test(recent)) {
|
|
|
+ return Optional.of(recent);
|
|
|
}
|
|
|
rem = end - System.nanoTime();
|
|
|
}
|
|
|
- return null;
|
|
|
+ return Optional.empty();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -428,25 +462,25 @@ public abstract class EventLock<E extends Event> {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event) throws InterruptedException {
|
|
|
+ public EE waitForEvent(Predicate<EE> condition) throws InterruptedException {
|
|
|
try {
|
|
|
- return super.waitForEvent(event);
|
|
|
+ return super.waitForEvent(condition);
|
|
|
} finally {
|
|
|
release();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public <T extends EE> T waitForEvent(Class<T> event, long timeout) throws InterruptedException {
|
|
|
+ public Optional<EE> waitForEvent(Predicate<EE> condition, long timeout) throws InterruptedException {
|
|
|
try {
|
|
|
- return super.waitForEvent(event, timeout);
|
|
|
+ return super.waitForEvent(condition, timeout);
|
|
|
} finally {
|
|
|
release();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public EE waitForEvent(long timeout) throws InterruptedException {
|
|
|
+ public Optional<EE> waitForEvent(long timeout) throws InterruptedException {
|
|
|
try {
|
|
|
return super.waitForEvent(timeout);
|
|
|
} finally {
|