Skip to content

refactor(session): collapse the request openers into a generic helper#29

Merged
floatdrop merged 2 commits into
draft-18from
refactor/generic-request-opener
Jun 28, 2026
Merged

refactor(session): collapse the request openers into a generic helper#29
floatdrop merged 2 commits into
draft-18from
refactor/generic-request-opener

Conversation

@floatdrop

@floatdrop floatdrop commented Jun 28, 2026

Copy link
Copy Markdown
Owner

What

Publish, Subscribe, Fetch, TrackStatus, PublishNamespace, SubscribeNamespace, and SubscribeTracks all repeated the same §10.1 request skeleton:

openAllocRequest(m) → readResponse(ctx) → switch { OK / REQUEST_ERROR / default } → wrap

Fetch and TrackStatus even carried //nolint:dupl waivers acknowledging the duplication.

This extracts a single generic primitive, awaitRequestResponse[OK, R], in request.go. It owns the open / await-OK / error-mapping skeleton and delegates only the success case — the expected OK message type and the typed-handle construction — to a per-opener closure:

func (s *Session) Subscribe(ctx context.Context, m *message.Subscribe) (*Subscription, error) {
	return awaitRequestResponse(ctx, s, m,
		func(stream Stream, ok *message.SubscribeOK) (*Subscription, error) {
			// validate properties, register alias, wrap…
		})
}

The REQUEST_ERROR → *RequestRejectedError mapping, the unexpected %s in X response error, and the read X response wrapping now live in one place instead of seven. The operation name in those errors is derived from m.Type() (which already stringifies to SUBSCRIBE, FETCH, TRACK_STATUS, …), so there is no redundant label to keep in sync.

Publish keeps its one distinguishing step — pre-allocating the Track Alias before the open — in the method body, then routes through the same helper (OpenPublish is just openAllocRequest, which the helper already calls).

Why

  • Removes ~170 lines of near-identical boilerplate.
  • Deletes both //nolint:dupl waivers — the duplication is gone, not suppressed.
  • Centralizes the response-dispatch and error-mapping logic so future changes (e.g. the "self-close on protocol violation" cleanup) touch one function.

Behavior

No behavior change. The helper checks the OK type first, then REQUEST_ERROR, then falls through to the unexpected-response error — identical ordering, outcomes, and error strings to the original type switches. OK is matched via a type assertion on the type parameter, which keys on the concrete wire type (*SubscribeOK, *FetchOK, *RequestOK; note TrackStatusOK = RequestOK).

Testing

  • go build ./...
  • go test ./... (full suite)
  • go test -race ./pkg/moqt/session/... ./pkg/relay/...
  • golangci-lint run ./pkg/moqt/session/... — 0 issues

🤖 Generated with Claude Code

Subscribe, Fetch, TrackStatus, PublishNamespace, SubscribeNamespace, and
SubscribeTracks all repeated the same §10.1 skeleton: openAllocRequest →
readResponse → switch on OK / REQUEST_ERROR / default → wrap. Fetch and
TrackStatus even carried //nolint:dupl waivers for it.

Extract awaitRequestResponse[OK, R], a generic primitive that owns the
open / await-OK / error-mapping skeleton and delegates only the success
case (OK type + handle construction) to a per-opener closure. The
REQUEST_ERROR → *RequestRejectedError mapping and the "unexpected response"
and "read X response" error strings now live in one place. The operation
name in those errors is derived from m.Type() rather than a passed-in label.

Net change removes both dupl waivers and ~150 lines of boilerplate; no
behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@floatdrop floatdrop force-pushed the refactor/generic-request-opener branch from 577285c to ba32e92 Compare June 28, 2026 19:29
Publish shares the same open / await-OK / error-mapping skeleton as the
other six openers; it differed only by pre-allocating its Track Alias
before opening (and OpenPublish is just openAllocRequest, which the helper
already calls). Route it through awaitRequestResponse too, keeping the
pre-open alias allocation in Publish itself. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@floatdrop floatdrop changed the title refactor(session): collapse six request openers into a generic helper refactor(session): collapse the request openers into a generic helper Jun 28, 2026
@floatdrop floatdrop merged commit 1e1244c into draft-18 Jun 28, 2026
9 checks passed
@floatdrop floatdrop deleted the refactor/generic-request-opener branch June 28, 2026 19:34
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.

1 participant