-
Notifications
You must be signed in to change notification settings - Fork 234
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
Supporting client-side gRPC cancellation #393
Conversation
@@ -1502,6 +1522,7 @@ def wrapped_callback(call_future): | |||
if request_id != "": | |||
verbose_message = verbose_message + " '{}'".format(request_id) | |||
print(verbose_message) | |||
return self._call_future |
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.
I think @nnshah1 had some concerns about returning this grpc future directly, not wanting users to call future.result()
on it, possibly conflicting with our own callback that blocks on the result. If we want to return a cancel-only future, we can wrap it and hide the underlying future/.result()
method.
However, I think it's fine to return it directly and document they shouldn't call .result()
on it for now.
I'll let Neelay comment on this.
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.
I would like us to define a "WrappedFuture" class, where we override the result() method to return an InferResult() (similar in that sense to the wrapped_callback). Or hide the result as @rmccorm4 mentioned.
I think returning a future but having the result() be different than with the callback will be non-intuitive. - also don't like the idea of documenting 'not to use result()' or 'result()' is different that InferResult() - all seem more confusing than to wrap it.
Let me know if it's feasible.
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.
Updated here: cdf8aea
self._active = True | ||
self._response_iterator = None | ||
|
||
def __del__(self): | ||
self.close() |
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.
I'd advocate for del to be non blocking and use self.close(cancel_requests=True) - unless I'm missing something / good reason to keep it blocking.
@@ -1451,6 +1452,23 @@ def async_infer( | |||
Optional custom parameters to be included in the inference | |||
request. | |||
|
|||
Returns |
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.
I think returning a future should replace the callback method. AFAIK, futures (or async/await) were added to replace the need for callbacks and we need to support one of them.
We could perhaps add another argument to async_infer
named return_future
with the default value of False
. If it is set to True, this method would return a future and would never call the callback.
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.
This makes sense. IMO we should also support cancelling request for callback based cancellation policy.
However, that is not possible without sending back the future. Maybe we can enforce that for accessing request cancellation feature, the user can not use callback based mode.
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.
Maybe we can enforce that for accessing request cancellation feature, the user can not use callback based mode.
Exactly, that's what I was thinking.
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.
I like the idea of returning Future with an additional method for retrieving the message. But I think it goes beyond the scope and can be addressed separately.
Additionally, we should be thinking of moving to aio clients at some point. Maintaining two library version is becoming heavy.
get_call_obj : bool | ||
If set True, then this function will yield | ||
grpc.aio.call object first bfore the | ||
InferResult. | ||
This object can be used to issue request | ||
cancellation if required. This can be attained | ||
by following: | ||
------- | ||
generator = client.infer(..., get_call_obj=True) | ||
grpc_call = await anext(generator) | ||
grpc_call.cancel() | ||
------- |
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.
Would it be possible to wrap the call object in another class (perhaps Request
) that once awaited would provide and has a cancel method?
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.
There are some new primitives that got added for async_generators in python 3.10. I am not very familiar with these right out of bat first trial was not successful.
Reverting cancellation support in asyncio for now. Will be addressing the issue later.
b947d73
to
0308aa4
Compare
Co-authored-by: Iman Tabrizian <iman.tabrizian@gmail.com>
70b590d
to
e568b72
Compare
* Supporting client-side gRPC cancellation (#393) * Supporting client-side gRPC cancellation * Address review comments * Wrap future to expose only cancel * Update src/python/library/tritonclient/grpc/_client.py Co-authored-by: Iman Tabrizian <iman.tabrizian@gmail.com> * Reverting changes in asyncio library * Format * Make class variable real private --------- Co-authored-by: Iman Tabrizian <iman.tabrizian@gmail.com> * Fix L0_grpc (#400) * Improve the check --------- Co-authored-by: Iman Tabrizian <iman.tabrizian@gmail.com>
Enhances python client API to issue gRPC cancellation.
C++ client side grpc cancellation will be added at a later point.
Tests are added here: triton-inference-server/server#6278