-
Notifications
You must be signed in to change notification settings - Fork 40
Refactor ParallelExecutor #2820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -147,7 +147,8 @@ public void executeImplicitPreRead(List<ParallelExecutorTask> tasks, String tran | |
| } | ||
| } | ||
|
|
||
| private void executeTasks( | ||
| @VisibleForTesting | ||
| void executeTasks( | ||
| List<ParallelExecutorTask> tasks, | ||
| boolean parallel, | ||
| boolean noWait, | ||
|
|
@@ -158,14 +159,14 @@ private void executeTasks( | |
| if (tasks.size() == 1 && !noWait) { | ||
| // If there is only one task and noWait is false, we can run it directly without parallel | ||
| // execution. | ||
| executeTasksSerially(tasks, stopOnError, taskName, transactionId); | ||
| tasks.get(0).run(); | ||
| return; | ||
| } | ||
|
|
||
| if (parallel) { | ||
| executeTasksInParallel(tasks, noWait, stopOnError, taskName, transactionId); | ||
| } else { | ||
| executeTasksSerially(tasks, stopOnError, taskName, transactionId); | ||
| executeTasksSerially(tasks, stopOnError); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -180,94 +181,92 @@ private void executeTasksInParallel( | |
|
|
||
| CompletionService<Void> completionService = | ||
| new ExecutorCompletionService<>(parallelExecutorService); | ||
| tasks.forEach( | ||
| t -> | ||
| completionService.submit( | ||
| () -> { | ||
| try { | ||
| t.run(); | ||
| } catch (Exception e) { | ||
| logger.warn( | ||
| "Failed to run a {} task. Transaction ID: {}", taskName, transactionId, e); | ||
| throw e; | ||
| } | ||
| return null; | ||
| })); | ||
|
|
||
| if (!noWait) { | ||
| Exception exception = null; | ||
| for (int i = 0; i < tasks.size(); i++) { | ||
| Future<Void> future = ScalarDbUtils.takeUninterruptibly(completionService); | ||
|
|
||
| try { | ||
| Uninterruptibles.getUninterruptibly(future); | ||
| } catch (java.util.concurrent.ExecutionException e) { | ||
| if (e.getCause() instanceof ExecutionException) { | ||
| if (!stopOnError) { | ||
| exception = (ExecutionException) e.getCause(); | ||
| } else { | ||
| throw (ExecutionException) e.getCause(); | ||
| } | ||
| } else if (e.getCause() instanceof ValidationConflictException) { | ||
| if (!stopOnError) { | ||
| exception = (ValidationConflictException) e.getCause(); | ||
| } else { | ||
| throw (ValidationConflictException) e.getCause(); | ||
| } | ||
| } else if (e.getCause() instanceof CrudException) { | ||
| if (!stopOnError) { | ||
| exception = (CrudException) e.getCause(); | ||
| } else { | ||
| throw (CrudException) e.getCause(); | ||
| // Submit tasks | ||
| for (ParallelExecutorTask task : tasks) { | ||
| completionService.submit( | ||
| () -> { | ||
| try { | ||
| task.run(); | ||
| } catch (Exception e) { | ||
| logger.warn( | ||
| "Failed to run a {} task. Transaction ID: {}", taskName, transactionId, e); | ||
|
Comment on lines
+192
to
+193
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to keep this log because, even after using |
||
| throw e; | ||
| } | ||
| } else if (e.getCause() instanceof RuntimeException) { | ||
| throw (RuntimeException) e.getCause(); | ||
| } else if (e.getCause() instanceof Error) { | ||
| throw (Error) e.getCause(); | ||
| return null; | ||
| }); | ||
| } | ||
|
|
||
| // Optionally wait for completion | ||
| if (noWait) { | ||
| return; | ||
| } | ||
|
|
||
| Throwable throwable = null; | ||
|
|
||
| for (int i = 0; i < tasks.size(); i++) { | ||
| Future<Void> future = ScalarDbUtils.takeUninterruptibly(completionService); | ||
| try { | ||
| Uninterruptibles.getUninterruptibly(future); | ||
| } catch (java.util.concurrent.ExecutionException e) { | ||
| Throwable cause = e.getCause(); | ||
|
|
||
| if (stopOnError) { | ||
| rethrow(cause); | ||
| } else { | ||
| if (throwable == null) { | ||
| throwable = cause; | ||
| } else { | ||
| throw new AssertionError("Can't reach here. Maybe a bug", e); | ||
| throwable.addSuppressed(cause); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated to use |
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!stopOnError && exception != null) { | ||
| if (exception instanceof ExecutionException) { | ||
| throw (ExecutionException) exception; | ||
| } else if (exception instanceof ValidationConflictException) { | ||
| throw (ValidationConflictException) exception; | ||
| } else { | ||
| throw (CrudException) exception; | ||
| } | ||
| } | ||
| // Rethrow exception if necessary | ||
| if (!stopOnError && throwable != null) { | ||
| rethrow(throwable); | ||
| } | ||
| } | ||
|
|
||
| private void executeTasksSerially( | ||
| List<ParallelExecutorTask> tasks, boolean stopOnError, String taskName, String transactionId) | ||
| private void executeTasksSerially(List<ParallelExecutorTask> tasks, boolean stopOnError) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The refactoring removed the logging of exceptions that occur during serial task execution. The private void executeTasksSerially(List<ParallelExecutorTask> tasks, boolean stopOnError, String taskName, String transactionId)
throws ExecutionException, ValidationConflictException, CrudException {
Exception exception = null;
for (ParallelExecutorTask task : tasks) {
try {
task.run();
} catch (ExecutionException | ValidationConflictException | CrudException e) {
logger.warn("Failed to run a {} task. Transaction ID: {}", taskName, transactionId, e);
if (!stopOnError) {
if (exception == null) {
exception = e;
} else {
exception.addSuppressed(e);
}
} else {
throw e;
}
}
}
if (!stopOnError && exception != null) {
rethrow(exception);
}
} |
||
| throws ExecutionException, ValidationConflictException, CrudException { | ||
| Exception exception = null; | ||
| for (ParallelExecutorTask task : tasks) { | ||
| try { | ||
| task.run(); | ||
| } catch (ExecutionException | ValidationConflictException | CrudException e) { | ||
|
||
| logger.warn("Failed to run a {} task. Transaction ID: {}", taskName, transactionId, e); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After using |
||
|
|
||
| if (!stopOnError) { | ||
| exception = e; | ||
| if (exception == null) { | ||
| exception = e; | ||
| } else { | ||
| exception.addSuppressed(e); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. Updated to use |
||
| } | ||
| } else { | ||
| throw e; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!stopOnError && exception != null) { | ||
| if (exception instanceof ExecutionException) { | ||
| throw (ExecutionException) exception; | ||
| } else if (exception instanceof ValidationConflictException) { | ||
| throw (ValidationConflictException) exception; | ||
| } else { | ||
| throw (CrudException) exception; | ||
| } | ||
| rethrow(exception); | ||
| } | ||
| } | ||
|
|
||
| private void rethrow(Throwable cause) | ||
| throws ExecutionException, ValidationConflictException, CrudException { | ||
| if (cause instanceof ExecutionException) { | ||
| throw (ExecutionException) cause; | ||
| } else if (cause instanceof ValidationConflictException) { | ||
| throw (ValidationConflictException) cause; | ||
| } else if (cause instanceof CrudException) { | ||
| throw (CrudException) cause; | ||
| } else if (cause instanceof RuntimeException) { | ||
| throw (RuntimeException) cause; | ||
| } else if (cause instanceof Error) { | ||
| throw (Error) cause; | ||
| } else { | ||
| throw new AssertionError("Unexpected exception type", cause); | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to directly call
tasks.get(0).run().