У меня есть набор классов, которые инкапсулируют единицу работы в Google Таблицах. После вызова метода execute класса они передают запрос в службу вместе с обратным вызовом, который служба должна вызывать по завершении задачи. (Поскольку задачи не являются критическими и часто повторяются, служба просто регистрирует ошибки и не вызывает класс, если его запрос не выполняется).
В разрезе задачи выглядят следующим образом:
public void execute() {
//preparatory stuff, then...
Request r = new Request(this::callback);
service.execute(r);
}
public void callback(Result result) {
...
}
Вызов службы является синхронным, но внутри службы запрос ставится в очередь, выполняется асинхронно, а обратный вызов вызывается в новом потоке. Некоторые задачи включают в себя несколько вызовов службы, методы обратного вызова могут сами создавать запрос со вторым методом обратного вызова и снова вызывать службу. Я хочу, чтобы это было невидимо для клиентского кода.
Моя проблема в том, что я хотел бы запускать задачи асинхронно из клиентского кода, а затем выполнять произвольный обработчик после того, как они будут выполнены. Один из способов сделать это - дать классу обратный вызов в методе execute (), который он будет вызывать после завершения выполнения. Но я бы предпочел сделать это встроенным в код, такого рода вещи:
CompletableFuture.supplyAsync(() -> (new Task()).execute()).whenComplete((result, error) -> {});
Проблема в том, что завершение метода execute () не сигнализирует об окончании задача, поскольку задача все еще ожидает обратного вызова. Другое дело, что обратный вызов может никогда не поступить. Я не могу понять, как я должен go вызывать задачу, чтобы я мог запускать ее асинхронно и встроенно, как в приведенном выше коде, и когда класс Task явно решит, что она завершена, будет вызываться whenComplete (). Мне также понадобится тайм-аут, так как обратный вызов задач не может быть вызван.
Есть идеи? Обратите внимание, что я контролирую службу, вызываемую задачами, поэтому я могу изменить ее работу, если это необходимо, но, вероятно, я бы предпочел этого не делать.