Add graph reinit on failure#4237
Conversation
There was a problem hiding this comment.
Pull request overview
Adds automatic MediaPipe graph reinitialization on inference failure when using the graph queue/pool, to prevent returning an errored (“poisoned”) graph instance back to the pool for reuse.
Changes:
- Introduces
GraphHelper::reinitialize()plus an RAIIGraphReinitGuardthat rebuilds a freshCalculatorGraphunless dismissed on the success path. - Hooks the guard into queue-based unary and streaming inference paths to trigger graph rebuild after failures.
- Moves per-graph shutdown logic into
GraphHelper’s destructor and simplifiesGraphQueuedestructor.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/mediapipe_internal/mediapipegraphexecutor.hpp |
Adds GraphReinitGuard around queue-path inference and dismisses it on success. |
src/mediapipe_internal/graphqueue.hpp |
Adds GraphHelper destructor, reinitialize() declaration, and new GraphReinitGuard type. |
src/mediapipe_internal/graphqueue.cpp |
Implements GraphHelper shutdown + reinit logic; defaults GraphQueue destructor. |
Comments suppressed due to low confidence (2)
src/mediapipe_internal/graphqueue.cpp:142
- reinitialize() sets graph to nullptr on ObserveOutputStream failure (graph.reset()). The next request acquiring this GraphHelper will dereference graphHelper->graph in GraphIdGuard (graph(*graphHelper->graph)), which can crash if graph is null. Ensure reinitialize() always leaves a non-null graph, or update acquisition logic to detect nullptr and rebuild/replace before use.
if (!absStatus.ok()) {
SPDLOG_ERROR("Graph reinitialize: ObserveOutputStream failed: {}", absStatus.ToString());
graph.reset();
return;
}
src/mediapipe_internal/graphqueue.cpp:162
- reinitialize() sets graph to nullptr on StartRun failure (graph.reset()). The next request acquiring this GraphHelper will dereference graphHelper->graph in GraphIdGuard (graph(*graphHelper->graph)), which can crash if graph is null. Ensure reinitialize() always leaves a non-null graph, or update acquisition logic to detect nullptr and rebuild/replace before use.
if (!absStatus.ok()) {
SPDLOG_ERROR("Graph reinitialize: StartRun failed: {}", absStatus.ToString());
graph.reset();
return;
}
| ~GraphReinitGuard() { | ||
| if (!dismissed) { | ||
| helper.reinitialize(config, sidePacketMaps); |
| void GraphHelper::reinitialize(const ::mediapipe::CalculatorGraphConfig& config, const GraphSidePackets& sidePacketMaps) { | ||
| SPDLOG_DEBUG("Reinitializing graph after error"); | ||
| // Tear down the old graph (best-effort, errors expected since graph is in bad state) | ||
| if (this->graph) { | ||
| auto absStatus = this->graph->CloseAllPacketSources(); |
| auto absStatus = graph->Initialize(config); | ||
| if (!absStatus.ok()) { | ||
| SPDLOG_ERROR("Graph reinitialize: Initialize failed: {}", absStatus.ToString()); | ||
| graph.reset(); | ||
| return; |
| graph->Cancel(); | ||
| } | ||
|
|
||
| void GraphHelper::reinitialize(const ::mediapipe::CalculatorGraphConfig& config, const GraphSidePackets& sidePacketMaps) { |
There was a problem hiding this comment.
Unit test that will ensure failed graphs are reusable is missing
| ~GraphReinitGuard() { | ||
| if (!dismissed) { | ||
| helper.reinitialize(config, sidePacketMaps); | ||
| } | ||
| } |
There was a problem hiding this comment.
In that case we could only log error anyway. Will add that.
| auto absStatus = graph->Initialize(config); | ||
| if (!absStatus.ok()) { | ||
| SPDLOG_ERROR("Graph reinitialize: Initialize failed: {}", absStatus.ToString()); | ||
| graph.reset(); | ||
| return; | ||
| } |
| if (!absStatus.ok()) { | ||
| SPDLOG_DEBUG("Graph queue WaitUntilDone error: {}", absStatus.ToString()); | ||
| SPDLOG_ERROR("Graph reinitialize: ObserveOutputStream failed: {}", absStatus.ToString()); | ||
| graph.reset(); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Will remove graph.reset.
| absStatus = graph->StartRun(inputSidePackets); | ||
| if (!absStatus.ok()) { | ||
| SPDLOG_ERROR("Graph reinitialize: StartRun failed: {}", absStatus.ToString()); | ||
| graph.reset(); | ||
| return; | ||
| } |
| #endif | ||
| if (log_level == "DEBUG" || log_level == "TRACE") { | ||
| #ifdef _WIN32 | ||
| _putenv_s("OPENVINO_LOG_LEVEL", "4"); |
There was a problem hiding this comment.
Not using guard utils since we dont want cyclic dependency on logging.
No description provided.