Skip to content

Commit 89514a0

Browse files
authored
update OrchestratorBlockedEvent and TaskFailedException to be uncheck… (#89)
* update OrchestratorBlockedEvent and TaskFailedException to be unchecked exception * update CHANGELOG.md
1 parent 921f5ff commit 89514a0

File tree

7 files changed

+22
-30
lines changed

7 files changed

+22
-30
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
* Updated package version to v1.0.0 - to be updated
1212
* update DataConverterException with detail error message ([#78](https://github.com/microsoft/durabletask-java/issues/78))
13+
* update OrchestratorBlockedEvent and TaskFailedException to be unchecked exceptions ([#88](https://github.com/microsoft/durabletask-java/issues/88))
1314

1415
### Breaking changes
1516

client/src/main/java/com/microsoft/durabletask/OrchestratorBlockedEvent.java renamed to client/src/main/java/com/microsoft/durabletask/OrchestratorBlockedException.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
* Control flow {@code Throwable} class for orchestrator functions. This {@code Throwable} must never be caught by user
77
* code.
88
* <p>
9-
* {@code OrchestratorBlockedEvent} is thrown when an orchestrator calls {@link Task#await} on an uncompleted task. The
9+
* {@code OrchestratorBlockedException} is thrown when an orchestrator calls {@link Task#await} on an uncompleted task. The
1010
* purpose of throwing in this way is to halt execution of the orchestrator to save the current state and commit any
11-
* side effects. Catching {@code OrchestratorBlockedEvent} in user code could prevent the orchestration from saving
11+
* side effects. Catching {@code OrchestratorBlockedException} in user code could prevent the orchestration from saving
1212
* state and scheduling new tasks, resulting in the orchestration getting stuck.
1313
*/
14-
public final class OrchestratorBlockedEvent extends Throwable {
15-
OrchestratorBlockedEvent(String message) {
14+
public final class OrchestratorBlockedException extends RuntimeException {
15+
OrchestratorBlockedException(String message) {
1616
super(message);
1717
}
1818
}

client/src/main/java/com/microsoft/durabletask/OrchestratorFunction.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ public interface OrchestratorFunction<R> {
1818
* @param ctx the orchestration context, which provides access to additional context for the current orchestration
1919
* execution
2020
* @return the serializable output of the orchestrator function
21-
* @throws OrchestratorBlockedEvent when the orchestrator blocks on an uncompleted task, which is a normal occurrence
22-
* @throws TaskFailedException when a task fails with an unhandled exception
2321
*/
24-
R apply(TaskOrchestrationContext ctx) throws OrchestratorBlockedEvent, TaskFailedException;
22+
R apply(TaskOrchestrationContext ctx);
2523
}

client/src/main/java/com/microsoft/durabletask/Task.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
package com.microsoft.durabletask;
44

55
import java.util.concurrent.CompletableFuture;
6-
import java.util.function.Consumer;
7-
import java.util.function.Function;
86

97
/**
108
* Represents an asynchronous operation in a durable orchestration.
@@ -16,13 +14,13 @@
1614
* </pre>
1715
* <p>
1816
* Orchestrator code uses the {@link #await()} method to block on the completion of the task and retrieve the result.
19-
* If the task is not yet complete, the {@code await()} method will throw an {@link OrchestratorBlockedEvent}, which
17+
* If the task is not yet complete, the {@code await()} method will throw an {@link OrchestratorBlockedException}, which
2018
* pauses the orchestrator's execution so that it can save its progress into durable storage and schedule any
2119
* outstanding work. When the task is complete, the orchestrator will run again from the beginning and the next time
2220
* the task's {@code await()} method is called, the result will be returned, or a {@link TaskFailedException} will be
2321
* thrown if the result of the task was an unhandled exception.
2422
* <p>
25-
* Note that orchestrator code must never catch {@code OrchestratorBlockedEvent} because doing so can cause the
23+
* Note that orchestrator code must never catch {@code OrchestratorBlockedException} because doing so can cause the
2624
* orchestration instance to get permanently stuck.
2725
*
2826
* @param <V> the return type of the task
@@ -54,9 +52,6 @@ public boolean isCancelled() {
5452
* Blocks the orchestrator until this task to complete, and then returns its result.
5553
*
5654
* @return the result of the task
57-
* @throws TaskFailedException if the task failed with an unhandled exception
58-
* @throws OrchestratorBlockedEvent if the task has not yet been scheduled, which is a normal occurrence.
59-
* This {@code Throwable} must never be caught in user code.
6055
*/
61-
public abstract V await() throws TaskFailedException, OrchestratorBlockedEvent;
56+
public abstract V await();
6257
}

client/src/main/java/com/microsoft/durabletask/TaskFailedException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Detailed information associated with a particular task failure can be retrieved using the {@link #getErrorDetails()}
1010
* method.
1111
*/
12-
public class TaskFailedException extends Exception {
12+
public class TaskFailedException extends RuntimeException {
1313
private final FailureDetails details;
1414
private final String taskName;
1515
private final int taskId;

client/src/main/java/com/microsoft/durabletask/TaskOrchestration.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ public interface TaskOrchestration {
6666
*
6767
* @param ctx provides access to methods for scheduling durable tasks and getting information about the current
6868
* orchestration instance.
69-
* @throws TaskFailedException when an orchestrator fails with an unhandled exception
70-
* @throws OrchestratorBlockedEvent when the orchestrator blocks on an uncompleted task, which is a normal occurrence
7169
*/
72-
void run(TaskOrchestrationContext ctx) throws TaskFailedException, OrchestratorBlockedEvent;
70+
void run(TaskOrchestrationContext ctx);
7371
}

client/src/main/java/com/microsoft/durabletask/TaskOrchestrationExecutor.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ public TaskOrchestratorResult execute(List<HistoryEvent> pastEvents, List<Histor
4242
// or we receive a yield signal
4343
while (context.processNextEvent()) { /* no method body */ }
4444
completed = true;
45+
} catch (OrchestratorBlockedException orchestratorBlockedException) {
46+
logger.fine("The orchestrator has yielded and will await for new events.");
4547
} catch (Exception e) {
4648
// The orchestrator threw an unhandled exception - fail it
4749
// TODO: What's the right way to log this?
4850
logger.warning("The orchestrator failed with an unhandled exception: " + e.toString());
4951
context.fail(new FailureDetails(e));
50-
} catch (OrchestratorBlockedEvent orchestratorBlockedEvent) {
51-
logger.fine("The orchestrator has yielded and will await for new events.");
5252
}
5353

5454
if (context.continuedAsNew || (completed && context.pendingActions.isEmpty() && !context.waitingForEvents())) {
@@ -712,11 +712,11 @@ private boolean waitingForEvents() {
712712
return this.outstandingEvents.size() > 0;
713713
}
714714

715-
private boolean processNextEvent() throws TaskFailedException, OrchestratorBlockedEvent {
715+
private boolean processNextEvent() {
716716
return this.historyEventPlayer.moveNext();
717717
}
718718

719-
private void processEvent(HistoryEvent e) throws TaskFailedException, OrchestratorBlockedEvent {
719+
private void processEvent(HistoryEvent e) {
720720
switch (e.getEventTypeCase()) {
721721
case ORCHESTRATORSTARTED:
722722
Instant instant = DataConverter.getInstantFromTimestamp(e.getTimestamp());
@@ -826,7 +826,7 @@ public OrchestrationHistoryIterator(List<HistoryEvent> pastEvents, List<HistoryE
826826
this.currentHistoryList = pastEvents;
827827
}
828828

829-
public boolean moveNext() throws TaskFailedException, OrchestratorBlockedEvent {
829+
public boolean moveNext() {
830830
if (this.currentHistoryList == pastEvents && this.currentHistoryIndex >= pastEvents.size()) {
831831
// Move forward to the next list
832832
this.currentHistoryList = this.newEvents;
@@ -860,7 +860,7 @@ public ExternalEventTask(String eventName, int taskId, Duration timeout) {
860860

861861
// TODO: Shouldn't this be throws TaskCanceledException?
862862
@Override
863-
protected void handleException(Throwable e) throws TaskFailedException {
863+
protected void handleException(Throwable e) {
864864
// Cancellation is caused by user-specified timeouts
865865
if (e instanceof CancellationException) {
866866
String message = String.format(
@@ -910,7 +910,7 @@ private RetriableTask(
910910
}
911911

912912
@Override
913-
public V await() throws TaskFailedException, OrchestratorBlockedEvent {
913+
public V await() {
914914
Instant startTime = this.context.getCurrentInstant();
915915
while (true) {
916916
Task<V> currentTask = this.taskFactory.create();
@@ -1024,7 +1024,7 @@ public CompletableTask() {
10241024
}
10251025

10261026
@Override
1027-
public V await() throws TaskFailedException, OrchestratorBlockedEvent {
1027+
public V await() {
10281028
do {
10291029
// If the future is done, return its value right away
10301030
if (this.future.isDone()) {
@@ -1039,14 +1039,14 @@ public V await() throws TaskFailedException, OrchestratorBlockedEvent {
10391039
} while (ContextImplTask.this.processNextEvent());
10401040

10411041
// There's no more history left to replay and the current task is still not completed. This is normal.
1042-
// The OrchestratorBlockedEvent throwable allows us to yield the current thread back to the executor so
1042+
// The OrchestratorBlockedException exception allows us to yield the current thread back to the executor so
10431043
// that we can send the current set of actions back to the worker and wait for new events to come in.
10441044
// This is *not* an exception - it's a normal part of orchestrator control flow.
1045-
throw new OrchestratorBlockedEvent(
1045+
throw new OrchestratorBlockedException(
10461046
"The orchestrator is blocked and waiting for new inputs. This Throwable should never be caught by user code.");
10471047
}
10481048

1049-
protected void handleException(Throwable e) throws TaskFailedException {
1049+
protected void handleException(Throwable e) {
10501050
if (e instanceof TaskFailedException) {
10511051
throw (TaskFailedException)e;
10521052
}

0 commit comments

Comments
 (0)