Skip to content

fix(nodes): stream twelvelabs video to disk instead of buffering in memory (#2564) - #2571

Open
kairavb wants to merge 2 commits into
rocketride-org:developfrom
kairavb:fix/RR-2564-twelvelabs-stream-to-disk
Open

kairavb wants to merge 2 commits into
rocketride-org:developfrom
kairavb:fix/RR-2564-twelvelabs-stream-to-disk

Conversation

@kairavb

@kairavb kairavb commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • twelvelabs streams incoming video straight to a temp file (BEGIN opens it, WRITE appends,
    END closes and submits) instead of collecting every chunk in a Python list first
  • A dangling stream (displaced by a fresh BEGIN, or still open when the instance is torn down
    via closing()) now gets its temp file released instead of leaked
  • README's "What it does" and "Submission lifecycle" notes updated to describe the new behavior

Type

Bug fix (non-breaking change which fixes an issue)

Testing

  • Tests added or updated
  • Tested locally
  • ./builder test passes

Added nodes/test/twelvelabs/test_streaming.py (6 cases), driving IInstance.writeVideo()
directly with twelvelabs_driver.process_video mocked, following the pattern in
nodes/test/thumbnail/test_chunk_ids.py. Ran:

./builder nodes:test-full --pytest-pattern="twelvelabs" --verbose

test/twelvelabs/test_streaming.py::test_video_is_streamed_to_disk_not_buffered_in_a_list PASSED
test/twelvelabs/test_streaming.py::test_temp_file_is_deleted_after_submission PASSED
test/twelvelabs/test_streaming.py::test_no_listener_skips_writing_text PASSED
test/twelvelabs/test_streaming.py::test_closing_releases_a_stream_that_never_got_an_end PASSED
test/twelvelabs/test_streaming.py::test_empty_response_falls_back_to_placeholder_text PASSED
test/twelvelabs/test_streaming.py::test_a_fresh_begin_discards_a_dangling_stream PASSED
test/test_contracts.py::TestNodeContracts::test_service_contract_valid[twelvelabs] PASSED
test/test_contracts.py::TestNodeContracts::test_node_module_exists[twelvelabs] PASSED
8 passed in 45.14s

Also ran ./builder docs:check — clean.

Checklist

  • Commit messages follow conventional commits
  • No secrets or credentials included
  • Wiki updated (if applicable)
  • Breaking changes documented (if applicable)

Linked Issue

Fixes #2564

Summary by CodeRabbit

  • Bug Fixes
    • Improved video processing reliability by writing incoming video data to a temporary file as it arrives, rather than holding all chunks in memory.
    • Incomplete streams are discarded instead of being submitted for analysis, and temporary files are cleaned up after processing or when the instance closes.
    • Empty analysis responses continue to display the existing fallback message.

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: rocketride-org/rocketride-server/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: fbbbbf88-902f-4572-8ae8-051f234f1e54

📥 Commits

Reviewing files that changed from the base of the PR and between a56f2f1 and 89eaaa3.


📒 Files selected for processing (1)
  • nodes/src/nodes/twelvelabs/IInstance.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.



📝 Walkthrough

Walkthrough

The TwelveLabs node now writes video chunks to a MIME-suffixed temporary file as they arrive. It submits the completed file on END and removes temporary files after submission or teardown. Regression tests cover chunk writing, response handling, listener gating, stream replacement, and cleanup.

Changes

TwelveLabs video streaming

Layer / File(s) Summary
Stream file lifecycle
nodes/src/nodes/twelvelabs/IInstance.py, nodes/src/nodes/twelvelabs/README.md
IInstance creates a temporary file at stream start, writes nonempty chunks as they arrive, and submits the file on END. Submission and teardown clean up temporary files. The README describes the updated lifecycle.
Streaming regression tests
nodes/test/twelvelabs/test_streaming.py
Tests cover streamed file contents, cleanup after submission, empty responses, listener gating, replacing an unfinished stream, and cleanup when closing() runs.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium


Merge Risk: ⚪ Minimal · up to 89eaa

Video chunks are written to a temporary file as they arrive, and the reviewed lifecycle does not remove an active stream before submission. No actionable merge-blocking risk is established.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 58.82% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: streaming TwelveLabs video to disk instead of buffering it in memory.
Linked Issues check Passed Issue #2564 requires bounded-memory handling of incoming video chunks. IInstance.writeVideo() now opens a temporary file on AVI_ACTION.BEGIN and writes each non-empty AVI_ACTION.WRITE buffer dir…
Out of Scope Changes check Passed The changes stay within issue #2564. The IInstance cleanup handles incomplete streams, the README documents the new streaming behavior, and the tests verify the implementation. No unrelated source o…

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added docs Documentation module:nodes Python pipeline nodes module:client-typescript TypeScript client SDK labels Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID and forum thread ID. Do not edit or delete.

@kairavb
kairavb force-pushed the fix/RR-2564-twelvelabs-stream-to-disk branch from 5e87d3d to a56f2f1 Compare October 9, 2026 14:15
@github-actions github-actions Bot removed the module:client-typescript TypeScript client SDK label Oct 9, 2026
joshuadarron
joshuadarron previously approved these changes Oct 9, 2026

@joshuadarron joshuadarron left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The change replaces the in-memory chunk list with a mkstemp file that is opened on BEGIN, appended on WRITE, and closed and submitted on END. Every exit path goes through one _discard_tmp_file(). Verified:

  • closing() is a real hook. The engine binds it (python-instance.target.cpp, PythonMethod::Closing) and calls it per document, before close. Several nodes use it (anonymize, extract_data, landing_ai). A stream that never got END is released when its document closes, which is the right scope.
  • Cleanup on every path. _submit_video's finally discards the file whether the submit succeeds or fails. A second BEGIN discards a dangling file first. END with no open file is now a no-op; previously it would have submitted an empty temp file.
  • Dropping os.path.realpath is safe: twelvelabs_driver.process_video only open()s the path.
  • Tests cover streaming, deletion after submit, no listener, closing() cleanup, empty response, and BEGIN displacement. CI is green, including Ruff, the docs build, and all three platform builds.

Nit (non-blocking): the closing() docstring says "when the instance is torn down". The engine calls closing() per document ("the current document is ready to close"), not at instance teardown (that's endInstance). Suggest: "Release a stream still open when its document closes without an END."

@kairavb

kairavb commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the closing() docstring nit from your review — thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation module:nodes Python pipeline nodes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

twelvelabs node buffers entire video in memory before writing to disk

2 participants