MCPcopy Create free account
hub / github.com/tensorflow/tensorboard / async_call_with_retries

Function async_call_with_retries

tensorboard/util/grpc_util.py:112–184  ·  view source on GitHub ↗

Initiate an asynchronous call to a gRPC stub, with retry logic. This is similar to the `async_call` API, except that the call is handled asynchronously, and the completion may be handled by another thread. The caller must provide a `done_callback` argument which will handle the resu

(api_method, request, clock=None)

Source from the content-addressed store, hash-verified

110
111
112def async_call_with_retries(api_method, request, clock=None):
113 """Initiate an asynchronous call to a gRPC stub, with retry logic.
114
115 This is similar to the `async_call` API, except that the call is handled
116 asynchronously, and the completion may be handled by another thread. The
117 caller must provide a `done_callback` argument which will handle the
118 result or exception rising from the gRPC completion.
119
120 Retries are handled with jittered exponential backoff to spread out failures
121 due to request spikes.
122
123 This only supports unary-unary RPCs: i.e., no streaming on either end.
124
125 Args:
126 api_method: Callable for the API method to invoke.
127 request: Request protocol buffer to pass to the API method.
128 clock: an interface object supporting `time()` and `sleep()` methods
129 like the standard `time` module; if not passed, uses the normal module.
130
131 Returns:
132 An `AsyncCallFuture` which will encapsulate the `grpc.Future`
133 corresponding to the gRPC call which either completes successfully or
134 represents the final try.
135 """
136 if clock is None:
137 clock = time
138 logger.debug("Async RPC call %s with request: %r", api_method, request)
139
140 completion_event = threading.Event()
141 async_future = AsyncCallFuture(completion_event)
142
143 def async_call(handler):
144 """Invokes the gRPC future and orchestrates it via the AsyncCallFuture."""
145 future = api_method.future(
146 request,
147 timeout=_GRPC_DEFAULT_TIMEOUT_SECS,
148 metadata=version_metadata(),
149 )
150 # Ensure we set the active future before invoking the done callback, to
151 # avoid the case where the done callback completes immediately and
152 # triggers completion event while async_future still holds the old
153 # future.
154 async_future._set_active_future(future)
155 future.add_done_callback(handler)
156
157 # retry_handler is the continuation of the `async_call`. It should:
158 # * If the grpc call succeeds: trigger the `completion_event`.
159 # * If there are no more retries: trigger the `completion_event`.
160 # * Otherwise, invoke a new async_call with the same
161 # retry_handler.
162 def retry_handler(future, num_attempts):
163 e = future.exception()
164 if e is None:
165 completion_event.set()
166 return
167 else:
168 logger.info("RPC call %s got error %s", api_method, e)
169 # If unable to retry, proceed to completion.

Callers

nothing calls this directly

Calls 2

AsyncCallFutureClass · 0.85
async_callFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…