A approach you could take is to send the request over the EventBus to start collection. The response would be just an acknowledgement. Your collector verticles would send data to a temp address the original request had stated. In each iteration of the loop the collector checks an “isCanceled” flag for the request which could be set by the other action.
Bonus track: wrap that into a flowable, so your business logic doesn’t need to know the eventbus Mechanic below it.
I described something like that recently.
To be very clear. When your code looks like this:
WorkerExecutor executor = vertx.createSharedWorkerExecutor("my-worker-pool");
executor.executeBlocking(promise -> {
// Call some blocking API that takes a significant amount of time to return
String result = someAPI.blockingMethod("hello");
promise.complete(result); },
res -> { System.out.println("The result is: " + res.result());
});
NOTHING will interrupt your someAPI.blockingMethod("hello");
call. The only thing you could do is to fail the promise at the end.
However, and I presume that's the case here, you wrote the someAPI
(to some extend). then you could do something like this:
public class CollectorVerticle extends AbstractVerticle {
private final ConcurrentMap <long, AtomicBoolean> cancelTracker = new ConcurrentHashMap<>();
...
Inside your execution:
final long key = Date.getTime(); // We use a Milisecond as key
executor.executeBlocking(promise -> {
// Call some blocking API that takes a significant amount of time to return
StringBuilder result = new StringBuilder();
someAPI.fixedblockingMethod(result, cancelTracker, key, "hello");
promise.complete(result.toString());
},
res -> {
if res.succeeded() {
System.out.println("The result is: " + res.result());
} else {
// Do whatever - check for error etc
}
cancelTracker.remove(key);
});
}
Then in your method along these lines:
fixedblockingMethod(StringBuilder b, Map cancelTracker, long key, String whatever) {
for (int i =0; i < eternity; i++) {
if (!cancelTracker.get(key).get() {
break;
}
b.append(getNextItemFromInterface();
}
}
That should do the trick.
I would still send individual items over the eventbus instead of collecting on the blocking method