Skip to content

Resolve server-side spec gaps - #116

Merged
kahrendt merged 2 commits into
mainfrom
fix/server-breaking-changes
Jul 13, 2026
Merged

Resolve server-side spec gaps#116
kahrendt merged 2 commits into
mainfrom
fix/server-breaking-changes

Conversation

@maximmaxim345

@maximmaxim345 maximmaxim345 commented Jul 2, 2026

Copy link
Copy Markdown
Member

The PR with server-implementation-breaking changes I mentioned in #113. Clients do not have to adjust anything for these; they tighten what a conforming server must do.

Specifically:

  • Role activation: a server MUST NOT activate a role or version the client did not list in supported_roles.
  • Forward compatibility: servers (not just clients) MUST ignore unrecognized payload fields, and MUST NOT send fields the spec does not define.
  • stream/request-format: a request the server cannot honor is not an error; the stream continues in a configuration the client supports. For players, stream/start MUST use a format from the client's supported_formats, so the server can never start a stream the client cannot decode.
  • Reconnect backoff: after repeated consecutive Noise-handshake failures, the server SHOULD NOT keep auto-reconnecting until there is reason to expect success (operator re-initiates pairing, network conditions change).
  • Artwork late join: after an artwork stream/start (initial or post-reconnect), the server SHOULD immediately send the current image for each channel whose source is not 'none', so a client joining mid-track is not left blank until the next track change.

@maximmaxim345
maximmaxim345 force-pushed the fix/available-state branch from 5b517e1 to feec536 Compare July 7, 2026 06:58
@maximmaxim345
maximmaxim345 force-pushed the fix/server-breaking-changes branch from f4c53e3 to 8ec0b89 Compare July 7, 2026 07:06
Base automatically changed from fix/available-state to main July 7, 2026 13:00
@maximmaxim345
maximmaxim345 force-pushed the fix/server-breaking-changes branch from 8ec0b89 to 46d514d Compare July 7, 2026 13:04
@maximmaxim345
maximmaxim345 marked this pull request as ready for review July 7, 2026 13:04
@kahrendt
kahrendt merged commit e98ec15 into main Jul 13, 2026
@kahrendt
kahrendt deleted the fix/server-breaking-changes branch July 13, 2026 12:39
maximmaxim345 added a commit to Sendspin/aiosendspin that referenced this pull request Jul 14, 2026
A batch of protocol-conformance and correctness fixes. This PR doesn't
include changes to encryption/authentication, that will follow in a
later PR.

## Changes

- **Adopt client/state `available` boolean.** Replace the client state
enum with the spec's `available` boolean end to end: the SDK sends only
`available`, the server tracks a boolean and notifies roles via
`on_availability_changed`. A legacy `state` enum on the wire normalizes
to `available`, with only `external_source` treated as unavailable so a
client reporting an error is not ejected from its group. Spec:
[#115](Sendspin/spec#115),
[#113](Sendspin/spec#113).
- **Stamp `server_transmitted` on stream lifecycle messages.** Add
`server_transmitted` to `stream/start`, `stream/clear`, and
`stream/end`, stamped at actual send time, matching `server/time`. Spec:
[#106](Sendspin/spec#106).
- **Floor send-ahead at `min_buffer`.** Live streams floor at
`min_buffer + static` instead of extending to `required_lead` (which
added latency a realtime queue cannot recover); buffered streams keep
the `min_buffer` floor instead of dropping to `required_lead + static`.
Spec: [#107](Sendspin/spec#107).
- **Document `seek_relative` clamping** as the application's
responsibility. Spec: [#103](Sendspin/spec#103).
- **Track all unimplemented client roles**, not just spec-support
families (controller/metadata/color and wholly-unknown families), still
excluding `_`-prefixed custom roles. Spec:
[#113](Sendspin/spec#113).
- **Make server reconnect per-goodbye-reason and activity-aware.** Retry
a server-initiated connection only on restart or concurrent_attempt; on
a drop with no goodbye, assume restart when the connection was idle or
carried playback, else treat it as a session end. Spec:
[#113](Sendspin/spec#113),
[#116](Sendspin/spec#116).
- **Default the visualizer pitch feature off** (rides reserved binary
type 21; kept as an opt-in extension). Spec:
[#86](Sendspin/spec#86).
- **Mask the beat downbeat bit** unless the role tracks downbeats. Spec:
[#86](Sendspin/spec#86).
- **Remember visualizer request-format when no stream is active**
instead of starting a stream in response (which the spec forbids).
Mirrors player/artwork. Spec:
[#112](Sendspin/spec#112).
- **Note peak-cadence deviation from spec** with a TODO (peak onset
detection currently runs only at the periodic `rate_max` hop). Spec:
[#86](Sendspin/spec#86).
- **Hoist binary-type sets out of the per-frame dispatch path** (reuse
module-level frozensets instead of rebuilding per binary frame).
- **Reset `_stream_started` after the artwork deactivate stream/end**,
matching the other stream roles.
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