-
Notifications
You must be signed in to change notification settings - Fork 0
v0.9.0 compliance: full upgrade against core/go reference #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Snider
wants to merge
140
commits into
main
Choose a base branch
from
dev
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
140 commits
Select commit
Hold shift + click to select a range
d10e9b5
fix(stream): preserve pipe channels and tcp auth metadata
0c17b05
fix(stream): add transport heartbeats and deadlines
3643665
refactor(stream): align adapters with AX conventions
5931bae
fix(stream): tighten hub and tcp lifecycle
77b6c51
fix(stream): close remaining RFC runtime gaps
a68c3e5
feat(stream): implement hub broker loop
3f55d1f
fix(stream): tighten hub and tcp edge cases
5505529
feat(stream): implement redis and zmq transports
14a6a6e
fix(hub): dispatch callbacks through hub queue
5f957f4
feat(zmq): add handshake auth for receivers
c39ea6e
feat(adapter): support direct HTTP handlers
22c9c9b
feat(ws): add legacy compatibility aliases
26eddad
refactor(adapter): use semantic receiver names
0782aee
feat(stream): add bridge delivery hooks
fceec98
fix(stream): forward pipe broadcasts
c4e50e2
feat(ws): restore legacy compatibility exports
21bfd41
feat(stream): add explicit subscription errors
6f803f8
fix(redis): enforce bridge startup lifecycle
8759314
fix(sse): default zero-value heartbeat config
9127d43
feat(ws): add channel handler
0cb8f0f
fix(tcp): preserve first payload without auth handshake
a1935bb
Implement inbound transport dispatch semantics
caa3380
fix(stream): honour peer transport shutdown
a15dd0e
refactor(stream): use semantic receiver names
ce4a7c6
refactor(stream): add AX-oriented usage examples
f5962ad
refactor(stream): align pipe fallback with broadcast semantics
daf343e
chore(stream): refine AX-facing APIs
1aace93
refactor(stream): align public docs with AX examples
d716256
fix(stream): harden auth and tcp first-frame handling
6e29d4a
fix(stream): generate proper peer UUIDs
10d54fb
fix(stream): keep overflow deliveries on hub loop
bb44ee5
fix(stream): re-export frame aliases
bdfa4db
fix(ws): add legacy compatibility facade
752a96e
fix(pipe): publish wildcard frames in generic fallback
e1abc27
docs(stream): apply AX examples to transport APIs
353f534
docs(stream): improve peer usage examples
45daa23
fix(zmq): enforce handshake size limit
b4aad18
fix(tcp): guarantee full-frame writes
7c94303
docs(stream): tighten AX-facing comments
b779ac9
feat(sse): add auth failure callback
1ce9483
docs(stream): add example-led adapter comments
3b55ed8
style(stream): clarify AX examples
41f62bb
refactor(stream): ax polish auth and docs
80c343f
refactor(stream): clarify auth adapter names
47a1b90
fix(stream): clone piped frames at bridge boundary
f49b9f2
docs(stream): align public comments with AX
e184c19
chore(stream): clarify auth result naming
70d5809
Add executable AX usage examples
089554a
style(stream): align public comments with AX
5bdeb4e
feat(stream): add predictable subscribe API
0ac22ad
docs(stream): make auth examples more concrete
c29ebf5
AX document stream message types
0179542
style(stream): align pipe naming with AX
a04e403
style(stream): align public comments with AX
6327cc7
style(stream): refine AX-facing examples
cdfaff7
style(stream): align public comments with AX
1f428f6
fix(stream): make pipe stops idempotent
df12f2c
style(stream): sharpen auth example
61dc2d8
Restore ws hub compatibility handlers
505ff76
refactor(stream): clarify hub internals
5925a8e
feat(stream): enforce channel authorisation at adapter edges
f859919
fix(tcp): handle nil dial context
4b4f49b
docs(stream): align public comments with AX
fa5e377
docs(stream): add usage examples for sentinel errors
709a1df
style(stream): clarify hub publish queue naming
ba8841d
style(stream): align message docs with AX
b02dd12
style(stream): align public comments with AX
3ae382c
Add TCP reconnect state tracking
a5f5919
style(stream): align config comments with AX
b193fca
style(stream): improve AX naming in pipe and message examples
14a33c2
docs(stream): confirm RFC parity
0a520e7
style(stream): align auth examples with AX
8ae82bc
style(stream): sharpen AX-facing public comments
3639063
style(stream): refine stats example
77663fd
style(stream): sharpen hub config AX comments
a565420
style(stream): sharpen AX comments
77c29e6
style(stream): add connection state stringer
237069c
style(stream): sharpen package comments for AX
5edc894
style(stream): sharpen hub comments for AX
4b70283
style(stream): tighten message type examples for AX
6381c9d
style(stream): sharpen AX public comments
93d5163
docs(ax): tighten API examples and names
8b0b796
docs(ax): sharpen adapter usage examples
626c2a7
style(stream): sharpen public examples
c351b66
AX polish transport examples
7abea98
fix(stream): close transports on context cancellation
8ef64e4
refactor(stream): name queue defaults
80d2660
style(stream): sharpen hub AX comments
8477c6b
feat(tcp): add client handshake support
ec3a152
style(stream): sharpen hub AX comments
3b25afc
style(ax): sharpen public API usage comments
b98af2b
style(ax): add composition usage examples
7469899
style(stream): sort peer iteration deterministically
954e692
feat(stream): add hub running accessor
9590535
style(stream): sharpen peer usage comments
cd7ef3d
Register ZMQ peers with the hub
0d3cfa1
docs(stream): align public examples with AX
a20177c
docs(stream): add RFC spec mirrors and AX comment polish
fad1ecb
docs(ax): add Codex conventions mirror
5a92e11
fix(transport): serialize reconnecting sends
e3f2a5b
style(stream): rename peer send queue field
7ebc142
style(stream): sharpen stream interface usage comments
3507a74
fix(hub): deliver peer-originated frames to sender
8d35382
fix(stream): reject adapters when hub is not running
438f81f
style(hub): sharpen public API examples
0ed78ee
style(ax): add concrete stream usage examples
9fe77e6
refactor(stream): clarify core names
01ecd9c
style(hub): sharpen running example comment
d68eec7
refactor(stream): rename peer internals for clarity
f9f66fd
style(ax): sharpen stream examples
120e388
chore(ax): replace mu with mutex
13fc477
ax(stream): add enum stringers for logging
ce6e043
docs(ax): align public comments with AX examples
a427005
style(ax): sharpen package examples
52382dc
style(ax): sharpen package docs
b5415b3
fix(hub): lock peer subscription state
79347bf
style(ax): sharpen package examples
4520fc0
fix(tcp): allow large unauthenticated initial frames
a13339e
fix(stream): count handler-only channels in stats
c9d74c0
style(ax): sharpen package docs
e9a66d6
style(ax): sharpen stream examples
ab8c74b
fix(ws): re-export channel authoriser alias
87a65d4
style(ax): sharpen stream examples
29832b4
fix(adapters): harden stream framing
df1c26e
docs(stream): improve auth examples
69b7ca3
style(ax): sharpen message envelope example
cf3be2c
style(ax): sharpen legacy ws compatibility example
7cf55bb
style(ax): default peer claims to empty map
37f5560
fix(auth): initialize successful claims maps
5306423
fix(adapter): register peers after transport setup
f29a9cb
style(stream): align peer internals with AX naming
e63b04e
refactor(tcp): clarify framing helper names
8a4cd2f
fix(redis): use bridge source ids directly
135249d
style(ax): align examples with core print helper
2c15a1f
style(ax): sharpen auth result example comments
e2f66c1
style(ax): sharpen pipe examples
fbf95ae
feat(ax): add comprehensive tests and usage-example comments
Snider 8f52f29
fix(ax): replace banned imports and add usage-example comments
Snider 0f88bbe
feat(ax-10): bring go-stream to v0.8.0-alpha.1 + CLI test scaffold
Snider 56dd1b1
refactor(core): full v0.9.0 compliance against core/go reference
Snider File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # CODEX.md — go-stream | ||
|
|
||
| This repository keeps its working conventions in [CLAUDE.md](/workspace/CLAUDE.md). | ||
|
|
||
| Read these two documents before changing code: | ||
|
|
||
| ```text | ||
| docs/RFC.md — go-stream implementation spec | ||
| docs/RFC-025-AGENT-EXPERIENCE.md — AX design principles | ||
| ``` | ||
|
|
||
| Key conventions: | ||
|
|
||
| - Use `core.E(scope, message, cause)` for errors. | ||
| - Keep comments as concrete usage examples. | ||
| - Prefer predictable names over shorthand. | ||
| - Preserve the transport-agnostic public API and the `ws` compatibility surface. | ||
|
|
||
| Commit convention: | ||
|
|
||
| ```text | ||
| type(scope): description | ||
|
|
||
| Co-Authored-By: Virgil <virgil@lethean.io> | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| // SPDX-License-Identifier: EUPL-1.2 | ||
|
|
||
| package redis | ||
|
|
||
| import ( | ||
| "github.com/alicebob/miniredis/v2" | ||
|
|
||
| core "dappco.re/go" | ||
| "dappco.re/go/stream" | ||
| ) | ||
|
|
||
| func ax7StartedBridge(t *core.T) (*Bridge, core.CancelFunc) { | ||
| redisServer := miniredis.RunT(t) | ||
| hub := stream.NewHub() | ||
| ctx, cancel := core.WithCancel(core.Background()) | ||
| go hub.Run(ctx) | ||
|
|
||
| bridge, err := NewBridge(hub, Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
| go func() { | ||
| if err := bridge.Start(ctx); err != nil { | ||
| t.Errorf("Start() error = %v", err) | ||
| } | ||
| }() | ||
| core.Sleep(100 * core.Millisecond) | ||
| return bridge, cancel | ||
| } | ||
|
|
||
| func TestAX7_NewBridge_Good(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| hub := stream.NewHub() | ||
|
|
||
| bridge, err := NewBridge(hub, Config{Addr: redisServer.Addr()}) | ||
| core.AssertNoError(t, err) | ||
| core.AssertEqual(t, hub, bridge.hub) | ||
| core.AssertEqual(t, "stream", bridge.config.Prefix) | ||
| } | ||
|
|
||
| func TestAX7_NewBridge_Bad(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
|
|
||
| bridge, err := NewBridge(nil, Config{Addr: redisServer.Addr()}) | ||
| core.AssertError(t, err) | ||
| core.AssertNil(t, bridge) | ||
| } | ||
|
|
||
| func TestAX7_NewBridge_Ugly(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| hub := stream.NewHub() | ||
|
|
||
| left, err := NewBridge(hub, Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
| right, err := NewBridge(hub, Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
| core.AssertNotEqual(t, left.SourceID(), right.SourceID()) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_SourceID_Good(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| bridge, err := NewBridge(stream.NewHub(), Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
|
|
||
| core.AssertNotEmpty(t, bridge.SourceID()) | ||
| core.AssertEqual(t, 36, core.RuneCount(bridge.SourceID())) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_SourceID_Bad(t *core.T) { | ||
| var bridge *Bridge | ||
|
|
||
| core.AssertEqual(t, "", bridge.SourceID()) | ||
| core.AssertNil(t, bridge) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_SourceID_Ugly(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| bridge, err := NewBridge(stream.NewHub(), Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
|
|
||
| sourceID := bridge.SourceID() | ||
| core.AssertEqual(t, sourceID, bridge.SourceID()) | ||
| core.AssertNotEmpty(t, sourceID) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Start_Good(t *core.T) { | ||
| bridge, cancel := ax7StartedBridge(t) | ||
| defer cancel() | ||
|
|
||
| bridge.mutex.RLock() | ||
| running := bridge.running | ||
| bridge.mutex.RUnlock() | ||
| core.AssertTrue(t, running) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Start_Bad(t *core.T) { | ||
| var bridge *Bridge | ||
|
|
||
| err := bridge.Start(core.Background()) | ||
| core.AssertError(t, err) | ||
| core.AssertContains(t, err.Error(), "nil bridge") | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Start_Ugly(t *core.T) { | ||
| bridge, cancel := ax7StartedBridge(t) | ||
| defer cancel() | ||
|
|
||
| err := bridge.Start(core.Background()) | ||
| core.AssertNoError(t, err) | ||
| core.AssertNotEmpty(t, bridge.SourceID()) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Stop_Good(t *core.T) { | ||
| bridge, cancel := ax7StartedBridge(t) | ||
| defer cancel() | ||
|
|
||
| core.AssertNoError(t, bridge.Stop()) | ||
| core.Sleep(50 * core.Millisecond) | ||
| bridge.mutex.RLock() | ||
| running := bridge.running | ||
| bridge.mutex.RUnlock() | ||
| core.AssertFalse(t, running) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Stop_Bad(t *core.T) { | ||
| var bridge *Bridge | ||
|
|
||
| core.AssertNoError(t, bridge.Stop()) | ||
| core.AssertNil(t, bridge) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_Stop_Ugly(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| bridge, err := NewBridge(stream.NewHub(), Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
|
|
||
| core.AssertNoError(t, bridge.Stop()) | ||
| core.AssertNotEmpty(t, bridge.SourceID()) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_PublishToChannel_Good(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| hub1 := stream.NewHub() | ||
| hub2 := stream.NewHub() | ||
| ctx, cancel := core.WithCancel(core.Background()) | ||
| defer cancel() | ||
| go hub1.Run(ctx) | ||
| go hub2.Run(ctx) | ||
| bridge1, err := NewBridge(hub1, Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
| bridge2, err := NewBridge(hub2, Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
| go func() { core.AssertNoError(t, bridge1.Start(ctx)) }() | ||
| go func() { core.AssertNoError(t, bridge2.Start(ctx)) }() | ||
| core.Sleep(100 * core.Millisecond) | ||
|
|
||
| received := make(chan []byte, 1) | ||
| stop := hub2.Subscribe("block", func(frame []byte) { received <- append([]byte(nil), frame...) }) | ||
| defer stop() | ||
| core.AssertNoError(t, bridge1.PublishToChannel("block", []byte("template"))) | ||
| core.AssertEqual(t, "template", string(<-received)) | ||
| } | ||
|
|
||
| func TestAX7_Bridge_PublishToChannel_Bad(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| bridge, err := NewBridge(stream.NewHub(), Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
|
|
||
| err = bridge.PublishToChannel("block", []byte("template")) | ||
| core.AssertError(t, err) | ||
| core.AssertContains(t, err.Error(), "not started") | ||
| } | ||
|
|
||
| func TestAX7_Bridge_PublishToChannel_Ugly(t *core.T) { | ||
| bridge, cancel := ax7StartedBridge(t) | ||
| defer cancel() | ||
|
|
||
| err := bridge.PublishToChannel("", []byte("template")) | ||
| core.AssertError(t, err) | ||
| core.AssertContains(t, err.Error(), "empty channel") | ||
| } | ||
|
|
||
| func TestAX7_Bridge_PublishBroadcast_Bad(t *core.T) { | ||
| redisServer := miniredis.RunT(t) | ||
| bridge, err := NewBridge(stream.NewHub(), Config{Addr: redisServer.Addr(), Prefix: "pool"}) | ||
| core.RequireNoError(t, err) | ||
|
|
||
| err = bridge.PublishBroadcast([]byte("shutdown")) | ||
| core.AssertError(t, err) | ||
| core.AssertContains(t, err.Error(), "not started") | ||
| } | ||
|
|
||
| func TestAX7_Bridge_PublishBroadcast_Ugly(t *core.T) { | ||
| var bridge *Bridge | ||
|
|
||
| err := bridge.PublishBroadcast([]byte("shutdown")) | ||
| core.AssertError(t, err) | ||
| core.AssertContains(t, err.Error(), "nil bridge") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // SPDX-License-Identifier: EUPL-1.2 | ||
|
|
||
| package redis_test | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "dappco.re/go/stream" | ||
| "dappco.re/go/stream/adapter/redis" | ||
| ) | ||
|
|
||
| func ExampleNewBridge() { | ||
| ctx, cancel := context.WithCancel(context.Background()) | ||
| defer cancel() | ||
|
|
||
| hub := stream.NewHub() | ||
| go hub.Run(ctx) | ||
|
|
||
| bridge, err := redis.NewBridge(hub, redis.Config{ | ||
| Addr: "127.0.0.1:6379", | ||
| Prefix: "pool", | ||
| }) | ||
| if err != nil { | ||
| return | ||
| } | ||
| defer bridge.Stop() | ||
|
|
||
| go func() { | ||
| _ = bridge.Start(ctx) | ||
| }() | ||
|
|
||
| _ = bridge.PublishToChannel("block", []byte("template")) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: dAppCore/go-stream
Length of output: 135
Change the path reference to
CLAUDE.mdto use a relative path instead of the absolute/workspace/path.The absolute path
/workspace/CLAUDE.mdis environment-specific and will break for users cloning the repository.CLAUDE.mdexists at the repository root and should be referenced relatively.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents