Skip to content

Add TCP stream buffering to SessionInitiationProtocol - #61

Merged
codingjoe merged 4 commits into
transactionsfrom
copilot/sub-pr-59
Mar 26, 2026
Merged

Add TCP stream buffering to SessionInitiationProtocol#61
codingjoe merged 4 commits into
transactionsfrom
copilot/sub-pr-59

Conversation

Copilot AI commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

data_received() assumed each TCP chunk was exactly one complete SIP message. TCP is a stream protocol — frames can be split across multiple deliveries or coalesced into one.

Changes

  • recv_buffer: bytearray — accumulates raw bytes from the TCP stream across data_received() calls
  • PING / PONG constants — module-level typing.Final[bytes] constants (b"\r\n\r\n" and b"\r\n") replace all scattered byte literals in the keepalive path
  • extract_frames() — generator that extracts complete frames from the buffer using Content-Length header framing (RFC 3261 §18.3); yields a memoryview into the buffer for each SIP message (zero-copy until Message.parse needs bytes) and the PING/PONG constants for keepalive frames; the view is explicitly released before the buffer is compacted; partial messages remain buffered until all bytes arrive
  • dispatch_frame() — routes a single complete frame (memoryview | bytes) to the appropriate handler, converting to bytes only at parse time
  • data_received() — appends to recv_buffer and iterates the extract_frames() generator
def data_received(self, data: bytes) -> None:
    self.recv_buffer.extend(data)
    for frame in self.extract_frames():
        self.dispatch_frame(frame)

Tests

39 new tests covering: split headers, split body, coalesced messages, all keepalive edge cases (partial PING, PONG-then-message, etc.), invalid Content-Length, and end-to-end data_received reassembly scenarios.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] [WIP] Address feedback on protocol structure refactor from PR #59 Add TCP stream buffering to SessionInitiationProtocol Mar 26, 2026
Copilot AI requested a review from codingjoe March 26, 2026 12:32
@codecov

codecov Bot commented Mar 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (transactions@62fbb93). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff               @@
##             transactions      #61   +/-   ##
===============================================
  Coverage                ?   87.66%           
===============================================
  Files                   ?       26           
  Lines                   ?     1954           
  Branches                ?        0           
===============================================
  Hits                    ?     1713           
  Misses                  ?      241           
  Partials                ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codingjoe codingjoe left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot instead of all the comments, try naming constants instead of byte literals for things like ping and pong. We also want to avoid copying too much data here and keep a low memory profile.

Comment thread voip/sip/protocol.py Outdated

Copilot AI commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

@copilot instead of all the comments, try naming constants instead of byte literals for things like ping and pong. We also want to avoid copying too much data here and keep a low memory profile.

Done in 78daf19. Added PING = b"\r\n\r\n" and PONG = b"\r\n" as typing.Final[bytes] module-level constants. All byte literals in the keepalive path are replaced with these, removing the need for inline comments. extract_frames also yields them directly for keepalive frames (no copy), and dispatch_frame + send_keepalive use them throughout.

Copilot AI requested a review from codingjoe March 26, 2026 14:37
@codingjoe
codingjoe marked this pull request as ready for review March 26, 2026 14:53
@codingjoe
codingjoe merged commit 69115ae into transactions Mar 26, 2026
13 checks passed
@codingjoe
codingjoe deleted the copilot/sub-pr-59 branch March 26, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants