public static final class Context.CancellableContext extends Context implements Closeable
This class must be cancelled by either calling close()
or cancel(java.lang.Throwable)
.
close()
is equivalent to calling cancel(null)
. It is safe to call the methods
more than once, but only the first call will have any effect. Because it's safe to call the
methods multiple times, users are encouraged to always call close()
at the end of
the operation, and disregard whether cancel(java.lang.Throwable)
was already called somewhere else.
Blocking code can use the try-with-resources idiom:
try (CancellableContext c = Context.current() .withDeadlineAfter(100, TimeUnit.MILLISECONDS, executor)) { Context toRestore = c.attach(); try { // do some blocking work } finally { c.detach(toRestore); } }
Asynchronous code will have to manually track the end of the CancellableContext's lifetime, and cancel the context at the appropriate time.
Context.CancellableContext, Context.CancellationListener, Context.Key<T>, Context.Storage
Modifier and Type | Method and Description |
---|---|
void |
addListener(Context.CancellationListener cancellationListener,
Executor executor)
Add a listener that will be notified when the context becomes cancelled.
|
Context |
attach()
Attach this context, thus enter a new scope within which this context is
Context.current() . |
boolean |
cancel(Throwable cause)
Cancel this context and optionally provide a cause (can be
null ) for the
cancellation. |
Throwable |
cancellationCause()
If a context
Context.isCancelled() then return the cause of the cancellation or
null if context was cancelled without a cause. |
void |
close()
Cleans up this object by calling
cancel(null) . |
void |
detach(Context toAttach)
Reverse an
attach() , restoring the previous context and exiting the current scope. |
void |
detachAndCancel(Context toAttach,
Throwable cause)
Cancel this context and detach it as the current context.
|
Deadline |
getDeadline()
A context may have an associated
Deadline at which it will be automatically cancelled. |
boolean |
isCancelled()
Is this context cancelled.
|
boolean |
isCurrent()
Deprecated.
This method violates some GRPC class encapsulation and should not be used.
If you must know whether a Context is the current context, check whether it is the same
object returned by
Context.current() . |
void |
removeListener(Context.CancellationListener cancellationListener)
Remove a
Context.CancellationListener . |
call, current, currentContextExecutor, fixedContextExecutor, fork, key, keyWithDefault, run, withCancellation, withDeadline, withDeadlineAfter, withValue, withValues, withValues, withValues, wrap, wrap
public Context attach()
Context
Context.current()
. The
previously current context is returned. It is allowed to attach contexts where Context.isCancelled()
is true
.
Instead of using attach()
and Context.detach(Context)
most use-cases are better
served by using the Context.run(Runnable)
or Context.call(java.util.concurrent.Callable)
to
execute work immediately within a context's scope. If work needs to be done in other threads it
is recommended to use the 'wrap' methods or to use a propagating executor.
All calls to attach()
should have a corresponding Context.detach(Context)
within
the same method:
Context previous = someContext.attach();
try {
// Do work
} finally {
someContext.detach(previous);
}
public void detach(Context toAttach)
Context
attach()
, restoring the previous context and exiting the current scope.
This context should be the same context that was previously attached
. The
provided replacement should be what was returned by the same attach()
call. If
an attach()
and a detach()
meet above requirements, they match.
It is expected that between any pair of matching attach()
and detach()
, all
attach()
es and detach()
es are called in matching pairs. If this method finds
that this context is not current
, either you or some code in-between are not
detaching correctly, and a SEVERE message will be logged but the context to attach will still
be bound. Never use Context.current().detach()
, as this will
compromise this error-detecting mechanism.
public void addListener(Context.CancellationListener cancellationListener, Executor executor)
Context
addListener
in class Context
public void removeListener(Context.CancellationListener cancellationListener)
Context
Context.CancellationListener
.removeListener
in class Context
@Deprecated public boolean isCurrent()
Context.current()
.public boolean cancel(Throwable cause)
null
) for the
cancellation. This will trigger notification of listeners. It is safe to call this method
multiple times. Only the first call will have any effect.
Calling cancel(null)
is the same as calling close()
.
true
if this context cancelled the context and notified listeners,
false
if the context was already cancelled.public void detachAndCancel(Context toAttach, Throwable cause)
toAttach
- context to make current.cause
- of cancellation, can be null
.public boolean isCancelled()
Context
isCancelled
in class Context
public Throwable cancellationCause()
Context
Context.isCancelled()
then return the cause of the cancellation or
null
if context was cancelled without a cause. If the context is not yet cancelled
will always return null
.
The cancellation cause is provided for informational purposes only and implementations should generally assume that it has already been handled and logged properly.
cancellationCause
in class Context
public Deadline getDeadline()
Context
Deadline
at which it will be automatically cancelled.getDeadline
in class Context
Deadline
or null
if no deadline is set.public void close()
cancel(null)
.close
in interface Closeable
close
in interface AutoCloseable