Add context manager support to InferencePipeline - #2939
Open
KushagraKanaujia wants to merge 1 commit into
Open
Conversation
Implements the Python context manager protocol (__enter__ / __exit__) for
InferencePipeline to enable safe resource cleanup with the 'with' statement.
## Problem
Currently, InferencePipeline requires manual lifecycle management:
```python
pipeline = InferencePipeline.init(...)
pipeline.start()
pipeline.join()
```
If ANY exception occurs between start() and join(), join() is never reached,
causing resource leaks:
- Orphaned inference and dispatching threads keep running
- ThreadPoolExecutor never shuts down
- Profiling traces are not saved to disk
Users must write verbose try/finally blocks to ensure cleanup, which is
error-prone and boilerplate-heavy.
## Solution
Added __enter__ and __exit__ methods following the same pattern as
VideoFileSink (already in the codebase at sinks.py:547-551).
### Changes
**inference/core/interfaces/stream/inference_pipeline.py**:
- Added __enter__() method returning self
- Added __exit__() method calling terminate() then join()
- Added comprehensive docstrings with usage examples
- Both methods are ~8 lines total
**tests/.../stream/test_context_manager.py**:
- New test suite with 8 test cases covering:
- Basic context manager protocol
- Exception handling and propagation
- Resource cleanup guarantees
- Typical usage patterns from the issue
## Usage
**Before (manual cleanup - prone to leaks)**:
```python
pipeline = InferencePipeline.init(
video_reference="./video.mp4",
model_id="my-model/1",
on_prediction=my_sink,
)
try:
pipeline.start()
except Exception:
pipeline.terminate()
pipeline.join()
raise
pipeline.join()
```
**After (automatic cleanup)**:
```python
with InferencePipeline.init(
video_reference="./video.mp4",
model_id="my-model/1",
on_prediction=my_sink,
) as pipeline:
pipeline.start()
# terminate() + join() called automatically, even on exceptions
```
## Benefits
✅ Prevents resource leaks (threads, thread pools, profiling data)
✅ Cleaner, more Pythonic API
✅ Follows established pattern (VideoFileSink uses same approach)
✅ Backward compatible - existing code continues to work
✅ Comprehensive test coverage
## Testing
All changes covered by test_context_manager.py:
- test_enter_returns_pipeline_instance
- test_exit_calls_terminate_and_join
- test_exit_calls_cleanup_on_exception
- test_context_manager_normal_execution
- test_context_manager_exception_handling
- test_context_manager_typical_usage_pattern
- And more...
Tests use mocking to verify cleanup order and exception handling
without requiring actual video sources or models.
Fixes roboflow#2744
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
KushagraKanaujia
requested review from
PawelPeczek-Roboflow,
dkosowski87,
grzegorz-roboflow,
hansent,
probicheaux,
rafel-roboflow and
yeldarby
as code owners
September 7, 2026 05:59
|
Kushagra Kanaujia seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
PawelPeczek-Roboflow
requested changes
Sep 11, 2026
PawelPeczek-Roboflow
left a comment
Collaborator
There was a problem hiding this comment.
TMP impediment - CLA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Python context manager protocol (
__enter__/__exit__) toInferencePipeline, enabling safe resource cleanup with thewithstatement.Problem
Currently,
InferencePipelinerequires manual lifecycle management that is prone to resource leaks:If any exception occurs between
start()andjoin(),join()is never reached, leaking:Users must write verbose try/finally blocks:
This is error-prone and boilerplate-heavy.
Solution
Implemented context manager protocol following the existing pattern used by
VideoFileSink(already in codebase atsinks.py:547-551).Implementation
Added two methods to
InferencePipeline:Total: ~40 lines (including comprehensive docstrings with examples)
Usage
Before (manual - error-prone)
After (automatic - safe)
Benefits
withstatement patternVideoFileSinkpattern in same codebaseTesting
Added comprehensive test suite in
test_context_manager.py:Test Coverage:
__enter__returns pipeline instance__exit__callsterminate()thenjoin()in correct orderAll tests use mocking to verify behavior without requiring actual video sources or models.
Design Decisions
Why this approach?
VideoFileSinkalready uses this exact pattern (sinks.py:547-551)Why
terminate()thenjoin()?From the issue (#2744):
Both must be called for clean shutdown. Order matters: signal stop first, then wait for completion.
Files Changed
inference/core/interfaces/stream/inference_pipeline.py__enter__()method (returnsself)__exit__()method (callsterminate()+join())tests/.../stream/test_context_manager.pyBackward Compatibility
✅ 100% backward compatible - No breaking changes
Existing code using manual lifecycle continues to work:
New code can use context manager for safety:
Related Issues
Fixes #2744
Acknowledgments
Thanks to the issue author for the excellent write-up and clear use case!
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com