Class MultiProgressMonitor
- java.lang.Object
-
- com.google.gerrit.server.git.MultiProgressMonitor
-
- All Implemented Interfaces:
com.google.gerrit.server.cancellation.RequestStateProvider
public class MultiProgressMonitor extends Object implements com.google.gerrit.server.cancellation.RequestStateProvider
Progress reporting interface that multiplexes multiple sub-tasks.Output is of the format:
Task: subA: 1, subB: 75% (3/4) (-)\r Task: subA: 2, subB: 75% (3/4), subC: 1 (\)\r Task: subA: 2, subB: 100% (4/4), subC: 1 (|)\r Task: subA: 4, subB: 100% (4/4), subC: 4, done \n
Callers should try to keep task and sub-task descriptions short, since the output should fit on one terminal line. (Note that git clients do not accept terminal control characters, so true multi-line progress messages would be impossible.)
Whether the client is disconnected or the deadline is exceeded can be checked by
checkIfCancelled(RequestStateProvider.OnCancelled)
. This allows the worker thread to react to cancellations and abort its execution and finish gracefully. After a cancellation has been signaled the worker thread has 10 *maxIntervalNanos
to react to the cancellation and finish gracefully. If the worker thread doesn't finish gracefully in time after the cancellation has been signaled, the future executing the task is forcefully cancelled which means that the worker thread gets interrupted and an internal error is returned to the client. To react to cancellations it is recommended that the task opens aRequestStateContext
in a try-with-resources block to register theMultiProgressMonitor
as aRequestStateProvider
. This way the worker thread gets aborted by aRequestCancelledException
when the request is cancelled which allows the worker thread to handle the cancellation gracefully by catching this exception (e.g. to return a proper error message).RequestCancelledException
is only thrown when the worker thread checks for cancellation viaRequestStateContext.abortIfCancelled()
. E.g. this is done wheneverTraceContext.TraceTimer
is opened/closed.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
MultiProgressMonitor.Factory
class
MultiProgressMonitor.Task
Handle for a sub-task.static class
MultiProgressMonitor.TaskKind
class
MultiProgressMonitor.VolatileTask
Handle for a sub-task whose total work can be updated while the task is in progress.
-
Field Summary
Fields Modifier and Type Field Description static int
UNKNOWN
Constant indicating the total work units cannot be predicted.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description MultiProgressMonitor.Task
beginSubTask(String subTask, int subTaskWork)
Begin a sub-task.MultiProgressMonitor.VolatileTask
beginVolatileSubTask(String subTask)
Begin a sub-task whose total work can be updated.void
checkIfCancelled(com.google.gerrit.server.cancellation.RequestStateProvider.OnCancelled onCancelled)
void
end()
End the overall task.<T> T
waitFor(Future<T> workerFuture)
Wait for a task managed by aFuture
, with no timeout.<T> T
waitFor(Future<T> workerFuture, long taskTimeoutTime, TimeUnit taskTimeoutUnit, long cancellationTimeoutTime, TimeUnit cancellationTimeoutUnit)
Wait for a task managed by aFuture
.<T> T
waitForNonFinalTask(Future<T> workerFuture)
Wait for a non-final task managed by aFuture
, with no timeout.<T> T
waitForNonFinalTask(Future<T> workerFuture, long taskTimeoutTime, TimeUnit taskTimeoutUnit, long cancellationTimeoutTime, TimeUnit cancellationTimeoutUnit)
Wait for a task managed by aFuture
.
-
-
-
Field Detail
-
UNKNOWN
public static final int UNKNOWN
Constant indicating the total work units cannot be predicted.- See Also:
- Constant Field Values
-
-
Method Detail
-
waitFor
public <T> T waitFor(Future<T> workerFuture)
Wait for a task managed by aFuture
, with no timeout.
-
waitFor
public <T> T waitFor(Future<T> workerFuture, long taskTimeoutTime, TimeUnit taskTimeoutUnit, long cancellationTimeoutTime, TimeUnit cancellationTimeoutUnit) throws TimeoutException
Wait for a task managed by aFuture
.Must be called from the main thread, not a worker thread. Once a worker thread calls
end()
, the future has an additionalmaxInterval
to finish before it is forcefully cancelled andExecutionException
is thrown.- Parameters:
workerFuture
- a future that returns when worker threads are finished.taskTimeoutTime
- overall timeout for the task; the future gets a cancellation signal after this timeout is exceeded; non-positive values indicate no timeout.taskTimeoutUnit
- unit for overall task timeout.cancellationTimeoutTime
- timeout for the task to react to the cancellation signal; if the task doesn't terminate within this time it is forcefully cancelled; non-positive values indicate no timeout.cancellationTimeoutUnit
- unit for the cancellation timeout.- Throws:
TimeoutException
- if this thread or a worker thread was interrupted, the worker was cancelled, or timed out waiting for a worker to callend()
.- See Also:
waitForNonFinalTask(Future, long, TimeUnit, long, TimeUnit)
-
waitForNonFinalTask
public <T> T waitForNonFinalTask(Future<T> workerFuture)
Wait for a non-final task managed by aFuture
, with no timeout.
-
waitForNonFinalTask
public <T> T waitForNonFinalTask(Future<T> workerFuture, long taskTimeoutTime, TimeUnit taskTimeoutUnit, long cancellationTimeoutTime, TimeUnit cancellationTimeoutUnit) throws TimeoutException
Wait for a task managed by aFuture
. This call does not expect the worker thread to callend()
. It is intended to be used to track a non-final task.- Parameters:
workerFuture
- a future that returns when worker threads are finished.taskTimeoutTime
- overall timeout for the task; the future is forcefully cancelled if the task exceeds the timeout. Non-positive values indicate no timeout.taskTimeoutUnit
- unit for overall task timeout.cancellationTimeoutTime
- timeout for the task to react to the cancellation signal; if the task doesn't terminate within this time it is forcefully cancelled; non-positive values indicate no timeout.cancellationTimeoutUnit
- unit for the cancellation timeout.- Throws:
TimeoutException
- if this thread or a worker thread was interrupted, the worker was cancelled, or timed out waiting for a worker to callend()
.
-
beginSubTask
public MultiProgressMonitor.Task beginSubTask(String subTask, int subTaskWork)
Begin a sub-task.- Parameters:
subTask
- sub-task name.subTaskWork
- total work units in sub-task, orUNKNOWN
.- Returns:
- sub-task handle.
-
beginVolatileSubTask
public MultiProgressMonitor.VolatileTask beginVolatileSubTask(String subTask)
Begin a sub-task whose total work can be updated.- Parameters:
subTask
- sub-task name.- Returns:
- sub-task handle.
-
end
public void end()
End the overall task.Must be called from a worker thread.
-
checkIfCancelled
public void checkIfCancelled(com.google.gerrit.server.cancellation.RequestStateProvider.OnCancelled onCancelled)
- Specified by:
checkIfCancelled
in interfacecom.google.gerrit.server.cancellation.RequestStateProvider
-
-