Skip to content

feat(go): harden ergonomic wrapper and unbreak just go check#1784

Merged
kixelated merged 2 commits into
devfrom
claude/awesome-mendel-c470e3
Jun 18, 2026
Merged

feat(go): harden ergonomic wrapper and unbreak just go check#1784
kixelated merged 2 commits into
devfrom
claude/awesome-mendel-c470e3

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

The two-tier Go binding was already in place (raw moq-go-ffi + ergonomic moq-go wrapper), but just go check was red and the wrapper had a few rough edges. This unbreaks the build and hardens the wrapper. No wire/protocol or moq-ffi changes; this is wrapper + tooling only. Targets dev because the wrapper API changes are breaking (Session and Transport were bare FFI aliases).

Pre-existing build fixes (the check was already failing on dev)

These two masked each other: the stale test failed go vet before linking was ever reached, so the missing framework never surfaced.

  • Stale test (moq_test.go) updated to the current PublishTrack / Consume / SubscribeMedia signatures (they gained info / subscription / maxLatencyMs params in an earlier refactor).
  • Missing CoreServices framework (cgo.go): libmoq_ffi.a pulls in the notify crate's FSEvents backend, so any binary link (i.e. go test) failed with undefined _FSEventStream* symbols on darwin. Added -framework CoreServices.

Wrapper hardening

  • Self-contained errors: all 19 FFI error variants re-exported as moq.Err* sentinels, plus IsAuthError, so consumers errors.Is without importing moq-go-ffi.
  • Session wrapped as a real type with Closed(ctx) / Shutdown() / Cancel(code) instead of a bare FFI alias; Serve uses it rather than reaching into the raw type.
  • Idempotent Close on Client and Server via sync.Once (Serve calls Server.Close on shutdown).
  • Transport promoted to a defined type with TransportQUIC / TransportIroh / TransportWebSocket.
  • Container constructors: LegacyContainer(), CmafContainer(init), LocContainer().
  • Catalog() reports ErrClosed on an empty stream instead of (nil, nil).
  • Cancellation semantics documented at the package level and in the README (the Used/Unused/Accept calls that have no native cancel).
  • Added runnable godoc examples (example_test.go).

Testing

  • check.sh now runs go test -race.
  • Added concurrency tests covering the runCancellable concurrent-cancel-during-pending-call path and repeated/concurrent Cancel. Both pass under the race detector, validating the core async-to-sync bridge.

Test plan

  • just go check passes (go vet, go build, go test -race)
  • New race tests run under -race and pass (TestRecvGroupCancelRace, TestConsumerCancelConcurrent)
  • gofmt -l clean

Public API changes (wrapper)

Breaking:

  • Session is now a struct, not a type alias for ffi.MoqSession; its methods are Closed(ctx), Shutdown(), Cancel(code uint32).
  • Transport is now a defined type (type Transport string) rather than an alias for string.

Additive:

  • moq.Err* error sentinels (19), IsAuthError.
  • TransportQUIC / TransportIroh / TransportWebSocket constants.
  • LegacyContainer / CmafContainer / LocContainer constructors.

(Written by Claude)

kixelated and others added 2 commits June 18, 2026 15:38
The two-tier Go binding (raw moq-go-ffi + ergonomic moq-go wrapper) was
already in place, but `just go check` was red and several rough edges
remained. This hardens the wrapper and fixes two pre-existing breakages
that masked each other (the stale test failed vet before linking was ever
reached, hiding the missing framework).

Pre-existing build fixes:
- Update moq_test.go to the current PublishTrack/Consume/SubscribeMedia
  signatures (they gained info/subscription/maxLatencyMs params).
- Add `-framework CoreServices` to the darwin cgo LDFLAGS. libmoq_ffi.a
  pulls in the notify crate's FSEvents backend, so any binary link
  (i.e. `go test`) failed with undefined _FSEventStream* symbols.

Wrapper hardening:
- Re-export all 19 FFI error variants as moq.Err* sentinels plus
  IsAuthError, so consumers errors.Is without importing moq-go-ffi.
- Wrap Session as a real type with Closed(ctx)/Shutdown()/Cancel(code)
  instead of a bare FFI alias; Serve uses it.
- Make Client.Close and Server.Close idempotent via sync.Once.
- Promote Transport to a defined type with TransportQUIC/Iroh/WebSocket.
- Add Container constructors (LegacyContainer/CmafContainer/LocContainer).
- Catalog() now reports ErrClosed on an empty stream instead of (nil, nil).
- Document cancellation semantics at the package level and in the README.

Testing:
- check.sh now runs `go test -race`.
- Add concurrency tests covering the runCancellable concurrent-cancel
  path and repeated/concurrent Cancel; both pass under the race detector.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review follow-ups:
- Client.Close/Server.Close: guard against a nil inner so calling Close
  on a zero-value Client/Server is a no-op (as it was before the sync.Once
  refactor) rather than panicking in the FFI layer.
- Rename ExampleClient_announced to ExampleClient_Announced so the example
  renders under the Announced method it demonstrates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated merged commit 417995a into dev Jun 18, 2026
11 checks passed
@kixelated kixelated deleted the claude/awesome-mendel-c470e3 branch June 18, 2026 23:15
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