Skip to content

feat: gsoc grained api - #5614

Merged
nugaon merged 34 commits into
masterfrom
feat/gsoc-grained-api
Sep 24, 2026
Merged

nugaon merged 34 commits into
masterfrom
feat/gsoc-grained-api

Conversation

@nugaon

@nugaon nugaon commented Sep 15, 2026

Copy link
Copy Markdown
Member

merging #5497 and #5593 PRs into one.

I took out the slow client handling part because the incoming updates frequency are unpredictable.
The feature is still notifying the user in case of piled up messages with warning log.

after the 1st master merge you can see the new code.


The following changes were made by Claude Sonnet 5 while chasing down the CI failures on this branch:

  • pkg/api/gsoc.go: replaced the fixed-size buffered channel + non-blocking default-drop ("slow consumer") logic with an unbounded FIFO queue (gsocQueue). The old default branch could silently drop a GSOC update on any goroutine-scheduling jitter (not just a genuinely slow client) and, after an earlier refactor, could also permanently hang Handle() — called synchronously by push/pull-sync — since nothing ever unblocked it for a client that never sends a close frame. The queue guarantees in-order delivery with no cap and no dropped messages, while a truly dead connection still times out via the existing per-message write deadline.
  • pkg/api/gsoc.go: moved Subscribe() to run synchronously in gsocWsHandler, before the connection is handed off to its own goroutine, closing a window where a GSOC update could arrive before the handler was registered and be silently missed.
  • pkg/api/gsoc_test.go: updated TestGsocWebsocketSlowConsumer to assert the new unbounded-queue behavior (the full backlog is delivered, in order, once the consumer catches up, instead of being disconnected), and added a synchronization fix specific to this test's in-memory net.Pipe transport — Dial() returning is not a happens-before guarantee that the server has reached Subscribe(), so the test now waits before sending and confirms with a throwaway round-trip before building the unread backlog it asserts on.
  • pkg/api/gsoc_test.go: removed the now-unnecessary fixed sleep between updates in TestGsocWebsocketMessageOrdering — ordering is guaranteed by the fix above rather than by pacing.

🤖 Generated with Claude Code

Add `Swarm-Soc-Fields` header to allow clients to request specific SOC fields (address, recoveredpubkey, identifier, signature, wrappedaddress, span, payload) in GSOC WebSocket messages. Add `Swarm-Cache-Wrapped-Chunk` header to enable caching of wrapped chunks on the node. Update GSOC handler to pass full SOC object instead of just payload, enabling access to all chunk properties. Adjust WebSocket buffer sizes to accommodate maximum SOC fields message size.
Add tests for `Swarm-Soc-Fields` header to verify requesting specific SOC fields (identifier, wrappedAddress, payload) and full wrapped chunk data (span + payload). Add test for `Swarm-Cache-Wrapped-Chunk` header to verify wrapped chunks are cached and retrievable. Update test helpers to support custom headers and return storer instance. Update gsoc handler signature to accept full SOC object instead of payload bytes.
gsoc.Handle spawned a goroutine per subscriber handler, so message
delivery order to a subscriber was not guaranteed. Call handlers
synchronously in registration order instead.
@nugaon
nugaon force-pushed the feat/gsoc-grained-api branch from f8f40ac to 8c0ba37 Compare September 15, 2026 08:31
@nugaon
nugaon marked this pull request as ready for review September 15, 2026 14:11
Comment thread pkg/api/gsoc.go
Comment thread pkg/api/gsoc.go Outdated
Comment thread pkg/api/gsoc.go Outdated
Comment thread pkg/api/api_test.go Outdated
Comment thread pkg/api/gsoc_test.go Outdated
Comment thread pkg/api/gsoc_test.go
Comment thread pkg/api/gsoc.go
Comment thread pkg/api/gsoc.go
Comment thread pkg/gsoc/gsoc.go

@martinconic martinconic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes look good, checked them manually also, but discovered with AI some things, please take a look

Comment thread pkg/api/gsoc.go Outdated
Comment thread pkg/api/gsoc.go
Comment thread pkg/api/gsoc.go Outdated
Comment thread pkg/api/gsoc.go Outdated
Comment thread pkg/gsoc/gsoc.go
go func(hh Handler) {
hh(c.WrappedChunk().Data()[swarm.SpanSize:])
}(*hh)
(*hh)(c)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure but should we add this instead, wdyt @janos ?

safe.Run(l.logger, "gsoc-handler", func() {
        (*hh)(c)
    })

@aloknerurkar
aloknerurkar dismissed their stale review September 23, 2026 11:15

Comments are addressed

@aloknerurkar aloknerurkar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for addressing all the comments. Changes look good from my end. Only additional thing is the comment from @martinconic around the loop and ping starvation. Once that is fixed I will approve it!

Comment thread pkg/api/gsoc.go
// connection, so it must not be aborted just because a websocket
// closes mid-write; it is bound to the node's lifetime instead.
wrapped := c.WrappedChunk()
safe.Go(s.logger, "gsoc-cache-wrapped-chunk", func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If I'm reading this right, it starts a new goroutine for every incoming message, and I don't see a limit. What would happen if someone floods this address or the disk is slow?

Would it make sense to cap it, maybe like gsocQueue ?

Also, it looks like these goroutines aren't tracked by wsWg. Could they still be writing after the storer is closed, or am I missing something?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah, it is handled by the queue mechanism in the code

@nugaon
nugaon merged commit 7f8015e into master Sep 24, 2026
15 checks passed
@nugaon
nugaon deleted the feat/gsoc-grained-api branch September 24, 2026 07:47
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.

4 participants