A Java 19 ShutdownOnFailure scope also allows for explicit cancellation of all tasks using the shutdown method. How can I know if the scope has been shutdown? The API includes an isShutdown method, but it is private.
Here is some (incomplete) code just to illustrate a possible use, where a scope is canceled some time after starting by the owner calling shutdown.
I guess that after a join() I could issue another scope.fork() and check if if returns a future to a canceled task but that seems weird. Is that the way to go?
ExecutorService executor = Executors.newCachedThreadPool();
try (StructuredTaskScope.ShutdownOnFailure scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<Integer> numOrders = scope.fork(Business::getNumItemsFromRequest);
Future<Double> price = scope.fork(Business::getPriceFromDB);
Business.sleepFor(500);
scope.shutdown(); // cancels all the scope tasks
//numOrders.cancel(true); // cancel just one task
scope.join(); // wait for all tasks
try {
scope.throwIfFailed();
// how would I know if scope was shutdown before all tasks completed?
System.out.println("Scope Completed Without Errors ( But possibly canceled ) ");
double amount = numOrders.get() * price.get();
Working code (as an experiment) located here.
Given this:
var result = "error";
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var numOrders = scope.fork(() -> taskGetNumItemsFromRequest());
var price = scope.fork(() -> taskGetPriceFromDB());
if (doShutdown) {
scope.shutdown();
}
scope.join();
scope.throwIfFailed();
result = numOrders.resultNow() + " " + price.resultNow();
} catch (Exception ex) {
if (ex != null) {
System.err.println("caught ex: " + ex.getClass());
System.err.println("caught ex message: " + ex.getMessage());
}
}
then this line:
result = numOrders.resultNow() + " " + price.resultNow();
will throw an Exception if the scope is shutdown. See the code for Future.resultNow()
.
It's unclear if you want to distinguish between other exception cases, such as closing the scope, or an exception thrown by a subtask? If you do want to distinguish, it would help to explain the reason in the question (i.e. the ultimate goal).
In general, there should be two paths: the happy-path for result
and then a path of an exception being thrown (for whatever reason).