@@ -107,27 +107,8 @@ PyDefaultArgumentToMutableType(const py::object& argument)
107
107
void
108
108
AsyncEventFutureDoneCallback (const py::object& py_future)
109
109
{
110
- // TODO: Why using `py_future.result()` with error hangs on exit?
111
- try {
112
- py::object exception = py_future.attr (" exception" )();
113
- if (!py::isinstance<py::none>(exception)) {
114
- std::string err_msg = " " ;
115
- py::object traceback = py::module_::import (" traceback" )
116
- .attr (" TracebackException" )
117
- .attr (" from_exception" )(exception)
118
- .attr (" format" )();
119
- for (py::handle line : traceback) {
120
- err_msg += py::str (line);
121
- }
122
- LOG_ERROR << err_msg;
123
- }
124
- }
125
- catch (const PythonBackendException& pb_exception) {
126
- LOG_ERROR << pb_exception.what ();
127
- }
128
- catch (const py::error_already_set& error) {
129
- LOG_ERROR << error.what ();
130
- }
110
+ std::unique_ptr<Stub>& stub = Stub::GetOrCreateInstance ();
111
+ stub->BackgroundFutureDone (py_future);
131
112
}
132
113
133
114
void
@@ -556,6 +537,7 @@ Stub::Initialize(bi::managed_external_buffer::handle_t map_handle)
556
537
c_python_backend_utils.attr (" shared_memory" ) = py::cast (shm_pool_.get ());
557
538
558
539
async_event_loop_ = py::none ();
540
+ background_futures_ = py::set ();
559
541
560
542
py::object TritonPythonModel = sys.attr (" TritonPythonModel" );
561
543
deserialize_bytes_ = python_backend_utils.attr (" deserialize_bytes_tensor" );
@@ -838,11 +820,47 @@ Stub::RunCoroutine(py::object coroutine, bool in_background)
838
820
py_future.attr (" add_done_callback" )(
839
821
py::module_::import (" c_python_backend_utils" )
840
822
.attr (" async_event_future_done_callback" ));
823
+ background_futures_.attr (" add" )(py_future);
841
824
return py::none ();
842
825
}
843
826
return py_future.attr (" result" )();
844
827
}
845
828
829
+ void
830
+ Stub::BackgroundFutureDone (const py::object& py_future)
831
+ {
832
+ ScopedDefer _ ([this , &py_future] {
833
+ // Remove future from background
834
+ try {
835
+ background_futures_.attr (" remove" )(py_future);
836
+ }
837
+ catch (const py::error_already_set& error) {
838
+ LOG_ERROR << " Cannot remove future from background; " << error.what ();
839
+ }
840
+ });
841
+ // TODO: Why using `py_future.result()` with error hangs on exit?
842
+ try {
843
+ py::object exception = py_future.attr (" exception" )();
844
+ if (!py::isinstance<py::none>(exception)) {
845
+ std::string err_msg = " " ;
846
+ py::object traceback = py::module_::import (" traceback" )
847
+ .attr (" TracebackException" )
848
+ .attr (" from_exception" )(exception)
849
+ .attr (" format" )();
850
+ for (py::handle line : traceback) {
851
+ err_msg += py::str (line);
852
+ }
853
+ LOG_ERROR << err_msg;
854
+ }
855
+ }
856
+ catch (const PythonBackendException& pb_exception) {
857
+ LOG_ERROR << pb_exception.what ();
858
+ }
859
+ catch (const py::error_already_set& error) {
860
+ LOG_ERROR << error.what ();
861
+ }
862
+ }
863
+
846
864
void
847
865
Stub::UpdateHealth ()
848
866
{
@@ -923,6 +941,7 @@ Stub::~Stub()
923
941
{
924
942
py::gil_scoped_acquire acquire;
925
943
async_event_loop_ = py::none ();
944
+ background_futures_ = py::none ();
926
945
model_instance_ = py::none ();
927
946
}
928
947
stub_instance_.reset ();
0 commit comments