feat(local-session): LOCAL session type, audio ingest task and session finalization - #9
Open
Rahulkaushik01 wants to merge 1 commit into
Conversation
…n finalization Turns queued audio into utterances and ends a local session cleanly. * SessionTypes.LOCAL so a Bot row can represent a local recording. * Ordering and exclusivity: segments drain from a per-source FIFO gated on a monotonic sequence, under a per-source lock, so exactly one drain owns the tail. A gap between segments is fed to the VAD as real silence rather than splicing speech together. Times derive from offset_ms, never a wall clock, so a skewed client clock cannot corrupt the timeline. * Ending: stop flushes every source's last utterance, marks the recording COMPLETE and only then moves READY -> ENDED. That order matters, otherwise the post-meeting transition marks a file-less local recording FAILED. The transition is state-guarded, so a retried stop is a no-op rather than an invalid-transition error. Bot state-change webhooks are skipped for LOCAL, which has no external subscribers. * A drain that finds the session already deleted exits quietly and clears its Redis state instead of erroring and retrying. LOCAL is excluded from the never-launched reaper, since a local recording launches no pod. Co-Authored-By: Claude <noreply@anthropic.com>
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 the
LOCALsession type and the Celery task that turns queued audio into utterances,plus the logic that ends a local session cleanly so it can be deleted.
Problem
the same audio in twice or out of sequence.
READYforever, anddelete_data()refuses to run on anything not in a terminal state — so users literally could not delete
their own recordings.
still-in-progress recording as
FAILED, and a local recording has no file to save it.How it works
sequence. Replays are dropped both against the tail and within the same batch, becausea retrying uploader can land two copies before any drain runs.
offset_ms(milliseconds since the session started),never the desktop's wall clock, so client clock skew cannot corrupt or drop audio. A gap
between segments is fed to the VAD as real silence instead of splicing speech together.
recording
COMPLETE→ only then movesREADY → ENDED. Completing first is what preventsthe post-meeting transition marking a file-less recording
FAILED. The transition isstate-guarded, so a retried or duplicate stop is a no-op rather than an
invalid-transition error.
LOCAL, which has no externalsubscribers and would otherwise deliver "bot" events to meeting-bot customers sharing
the project.
its Redis state instead of erroring and retrying.
LOCALis excluded from the never-launched reaper, since a local recording launches no podand therefore never heartbeats that way.
Changes made
bots/tasks/process_local_audio_segment_task.pybots/models.pySessionTypes.LOCAL,local_id prefix,LOCAL_SESSION_ENDEDevent + transition, webhook skipbots/migrations/0088,0089bots/management/commands/clean_up_bots_…bots/tasks/deliver_webhook_task.pyTotal: +226 / −15 (241 changed lines), 1 commit.
Testing performed
ruff check→ All checks passed;ruff format --check→ cleanpython manage.py check→ no issuesENDED, recording isCOMPLETEnotFAILED,transcript populated
delete_dataverified →DATA_DELETED, utterances removedand clears leftover state
python manage.py test bots.tests.test_cleanup→ 21/21 OKCoding-guidelines compliance
bots/models.pyispre-existing at ~3300 lines, over the 350 hard cap; this PR adds 30 lines to it because
a Django enum value and a state transition must live in the model module. Flagged per §2 —
see Refactoring recommendation below.
_drainis 69 lines (over the 50 guidance). It was already long;this PR's change to it is ~6 lines. Recommend extracting the segment-merge loop in a
follow-up, with tests.
MAX_SEGMENTS_PER_DRAIN, TTL constants, no magic numbers.deliberately rather than retried into a loop.
type(scope): description.Refactoring recommendation (§2 flag)
bots/models.pybreaches the file cap. I recommend not splitting it in this fork: thehistory shows ~3810 commits from the upstream author versus a handful of ours, and
models.pyis the most-edited file upstream — restructuring it would turn every future upstream sync into
a large manual conflict, permanently. Our footprint there is deliberately minimal (30 lines),
with all genuinely new logic in new, compliant files. If the split is wanted, the right move is
to propose it upstream and inherit it.
Risks / notes
0088/0089are choices-only (no data change). Numbering may need rebasingat
dev→prodconvergence.ruff format --checkis already red on two pre-existing test files ondev(
test_zoom_bot.py,test_bot_cpu_request.py) — unrelated to this PR.