Compare commits

...

5 Commits

Author SHA1 Message Date
argoyle 87d1e631f9 Merge pull request 'fix(deps): update golang.org/x/net to v0.51.0' (#746) from fix-vulncheck-xnet into main
Release / release (push) Successful in 1m17s
schemas / vulnerabilities (push) Successful in 3m20s
schemas / check-release (push) Successful in 4m5s
schemas / check (push) Successful in 5m59s
pre-commit / pre-commit (push) Successful in 9m7s
schemas / build (push) Successful in 6m50s
schemas / deploy-prod (push) Successful in 1m13s
Reviewed-on: #746
2026-03-03 08:22:09 +00:00
argoyle c98df1b4e7 fix(deps): update golang.org/x/net to v0.51.0
schemas / vulnerabilities (pull_request) Successful in 2m4s
schemas / check-release (pull_request) Successful in 4m15s
schemas / check (pull_request) Successful in 5m19s
pre-commit / pre-commit (pull_request) Successful in 9m45s
schemas / build (pull_request) Successful in 9m1s
schemas / deploy-prod (pull_request) Has been skipped
2026-03-03 09:03:39 +01:00
renovate 7bd605d90f fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.257 (#743)
Release / release (push) Failing after 1m16s
schemas / vulnerabilities (push) Successful in 2m20s
schemas / check-release (push) Successful in 3m46s
schemas / check (push) Successful in 4m47s
pre-commit / pre-commit (push) Successful in 9m12s
schemas / build (push) Successful in 6m18s
schemas / deploy-prod (push) Successful in 1m2s
2026-02-25 15:22:49 +00:00
argoyle 60bec67023 Merge pull request 'fix(graph): stabilize debouncer tests with synctest fake clock' (#741) from fix-flaky-debouncer-test into main
Release / release (push) Successful in 1m15s
schemas / vulnerabilities (push) Successful in 2m43s
schemas / check-release (push) Successful in 4m22s
schemas / check (push) Successful in 6m22s
pre-commit / pre-commit (push) Successful in 12m20s
schemas / build (push) Successful in 9m21s
schemas / deploy-prod (push) Successful in 1m13s
Reviewed-on: #741
2026-02-25 12:49:10 +00:00
argoyle cc33c651cd fix(graph): stabilize debouncer tests with synctest fake clock
schemas / vulnerabilities (pull_request) Successful in 2m17s
schemas / check-release (pull_request) Successful in 4m9s
schemas / check (pull_request) Successful in 4m52s
pre-commit / pre-commit (pull_request) Successful in 9m43s
schemas / build (pull_request) Successful in 6m58s
schemas / deploy-prod (pull_request) Has been skipped
Replace real time.Sleep waits with testing/synctest fake clock to
eliminate CI flakiness caused by timer races on loaded machines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:25:18 +01:00
3 changed files with 46 additions and 34 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ require (
github.com/sparetimecoders/goamqp v0.3.3 github.com/sparetimecoders/goamqp v0.3.3
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
github.com/vektah/gqlparser/v2 v2.5.32 github.com/vektah/gqlparser/v2 v2.5.32
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256 github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.257
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1 gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4 gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4
gitlab.com/unboundsoftware/eventsourced/pg v1.18.4 gitlab.com/unboundsoftware/eventsourced/pg v1.18.4
@@ -80,7 +80,7 @@ require (
go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.33.0 // indirect golang.org/x/mod v0.33.0 // indirect
golang.org/x/net v0.50.0 // indirect golang.org/x/net v0.51.0 // indirect
golang.org/x/sys v0.41.0 // indirect golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect golang.org/x/text v0.34.0 // indirect
golang.org/x/tools v0.42.0 // indirect golang.org/x/tools v0.42.0 // indirect
+4 -4
View File
@@ -198,8 +198,8 @@ github.com/wundergraph/astjson v1.1.0 h1:xORDosrZ87zQFJwNGe/HIHXqzpdHOFmqWgykCLV
github.com/wundergraph/astjson v1.1.0/go.mod h1:h12D/dxxnedtLzsKyBLK7/Oe4TAoGpRVC9nDpDrZSWw= github.com/wundergraph/astjson v1.1.0/go.mod h1:h12D/dxxnedtLzsKyBLK7/Oe4TAoGpRVC9nDpDrZSWw=
github.com/wundergraph/go-arena v1.1.0 h1:9+wSRkJAkA2vbYHp6s8tEGhPViRGQNGXqPHT0QzhdIc= github.com/wundergraph/go-arena v1.1.0 h1:9+wSRkJAkA2vbYHp6s8tEGhPViRGQNGXqPHT0QzhdIc=
github.com/wundergraph/go-arena v1.1.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw= github.com/wundergraph/go-arena v1.1.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256 h1:IlLfd3qL4THUkxSXsVRwcDNCAPNXqDrflMI0Hbvlb/Q= github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.257 h1:hGsaKXRkH3o8DkyizY48/wC1Q+NB1nfD9EKVA7Gc81Y=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256/go.mod h1:gfmmrPd2khZONmwYE8RIfnGjwIG+RqL52jYiBzcUST8= github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.257/go.mod h1:gfmmrPd2khZONmwYE8RIfnGjwIG+RqL52jYiBzcUST8=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1 h1:X6269JoAzHIKCVmtgMHZH3m7xOpACSp37ca3eODe9iU= gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1 h1:X6269JoAzHIKCVmtgMHZH3m7xOpACSp37ca3eODe9iU=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1/go.mod h1:EAs0d6Eh0aDiQkUJlSWErHqgHFQdxx0e8I7aG/2FarY= gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1/go.mod h1:EAs0d6Eh0aDiQkUJlSWErHqgHFQdxx0e8I7aG/2FarY=
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4 h1:+yZkhi9/sTyBEN5vJTfvycyXgGrm07QKGSh3jiWiQdM= gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4 h1:+yZkhi9/sTyBEN5vJTfvycyXgGrm07QKGSh3jiWiQdM=
@@ -251,8 +251,8 @@ golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+40 -28
View File
@@ -3,6 +3,7 @@ package graph
import ( import (
"sync/atomic" "sync/atomic"
"testing" "testing"
"testing/synctest"
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -10,48 +11,59 @@ import (
) )
func TestDebouncer_Coalesces(t *testing.T) { func TestDebouncer_Coalesces(t *testing.T) {
d := NewDebouncer(50 * time.Millisecond) synctest.Test(t, func(t *testing.T) {
var calls atomic.Int32 d := NewDebouncer(50 * time.Millisecond)
var calls atomic.Int32
// Fire 10 rapid calls for the same key — only the last should execute. // Fire 10 rapid calls for the same key — only the last should execute.
for range 10 { for range 10 {
d.Debounce("key1", func() { d.Debounce("key1", func() {
calls.Add(1) calls.Add(1)
}) })
} }
// Wait for the debounce delay plus some margin. // Advance fake clock past the debounce delay and let goroutines settle.
time.Sleep(150 * time.Millisecond) time.Sleep(50 * time.Millisecond)
synctest.Wait()
assert.Equal(t, int32(1), calls.Load(), "rapid calls should coalesce into a single execution") assert.Equal(t, int32(1), calls.Load(), "rapid calls should coalesce into a single execution")
})
} }
func TestDebouncer_DifferentKeys(t *testing.T) { func TestDebouncer_DifferentKeys(t *testing.T) {
d := NewDebouncer(50 * time.Millisecond) synctest.Test(t, func(t *testing.T) {
var calls atomic.Int32 d := NewDebouncer(50 * time.Millisecond)
var calls atomic.Int32
d.Debounce("key-a", func() { calls.Add(1) }) d.Debounce("key-a", func() { calls.Add(1) })
d.Debounce("key-b", func() { calls.Add(1) }) d.Debounce("key-b", func() { calls.Add(1) })
d.Debounce("key-c", func() { calls.Add(1) }) d.Debounce("key-c", func() { calls.Add(1) })
time.Sleep(150 * time.Millisecond) time.Sleep(50 * time.Millisecond)
synctest.Wait()
assert.Equal(t, int32(3), calls.Load(), "different keys should fire independently") assert.Equal(t, int32(3), calls.Load(), "different keys should fire independently")
})
} }
func TestDebouncer_TimerReset(t *testing.T) { func TestDebouncer_TimerReset(t *testing.T) {
d := NewDebouncer(100 * time.Millisecond) synctest.Test(t, func(t *testing.T) {
var value atomic.Int32 d := NewDebouncer(100 * time.Millisecond)
var value atomic.Int32
// First call sets value to 1. // First call sets value to 1.
d.Debounce("key", func() { value.Store(1) }) d.Debounce("key", func() { value.Store(1) })
// Wait 60ms (less than the 100ms delay), then replace with value 2. // Advance 60ms (less than the 100ms delay) — first timer hasn't fired.
time.Sleep(60 * time.Millisecond) time.Sleep(60 * time.Millisecond)
d.Debounce("key", func() { value.Store(2) })
// At 60ms the first timer hasn't fired yet. Wait for the second timer. // Replace with value 2 — resets the timer to fire at 60+100 = 160ms.
time.Sleep(150 * time.Millisecond) d.Debounce("key", func() { value.Store(2) })
require.Equal(t, int32(2), value.Load(), "later call should replace the earlier one") // Advance another 100ms (total 160ms) to fire the reset timer.
time.Sleep(100 * time.Millisecond)
synctest.Wait()
require.Equal(t, int32(2), value.Load(), "later call should replace the earlier one")
})
} }