Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ go 1.27.3
require (
github.com/alecthomas/kong v1.16.1
github.com/aws/aws-sdk-go-v2 v1.47.3
github.com/aws/aws-sdk-go-v2/config v1.33.6
github.com/aws/aws-sdk-go-v2/credentials v1.20.6
github.com/aws/aws-sdk-go-v2/config v1.33.8
github.com/aws/aws-sdk-go-v2/credentials v1.20.8
github.com/aws/aws-sdk-go-v2/service/eks v1.104.2
github.com/aws/aws-sdk-go-v2/service/rds v1.130.3
github.com/aws/aws-sdk-go-v2/service/route53 v1.70.1
github.com/aws/aws-sdk-go-v2/service/route53 v1.70.3
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.50.4
github.com/aws/aws-sdk-go-v2/service/sts v1.51.1
github.com/aws/aws-sdk-go-v2/service/sts v1.51.3
github.com/aws/smithy-go v1.28.5
github.com/coreos/go-oidc/v3 v3.21.0
github.com/evanw/esbuild v0.28.2
Expand All @@ -28,7 +28,7 @@ require (
github.com/pion/stun/v4 v4.0.1
github.com/pires/go-proxyproto v0.15.0
github.com/pressly/goose/v3 v3.28.0
github.com/prometheus/client_golang v1.24.1
github.com/prometheus/client_golang v1.25.0
github.com/prometheus/client_model v0.6.3
github.com/prometheus/common v0.72.0
github.com/prometheus/otlptranslator v1.0.0
Expand All @@ -47,7 +47,7 @@ require (
go.opentelemetry.io/otel/sdk/log v1.47.0
go.opentelemetry.io/otel/sdk/metric v1.47.0
go.opentelemetry.io/otel/trace v1.47.0
go.opentelemetry.io/proto/otlp v1.11.0
go.opentelemetry.io/proto/otlp v1.11.1
go.yaml.in/yaml/v3 v3.0.5
golang.org/x/crypto v0.58.0
golang.org/x/net v0.62.0
Expand All @@ -65,15 +65,15 @@ require (
require (
filippo.io/edwards25519 v1.2.0 // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.20.1 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.20.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.21 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.6 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.10.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.38.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.43.1 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.10.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.38.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.43.3 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.2 // indirect
Expand All @@ -87,7 +87,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus/v5 v5.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.31.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
Expand Down Expand Up @@ -118,7 +118,7 @@ require (
golang.org/x/sync v0.24.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260928230214-8a89bd6388cc // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260928230214-8a89bd6388cc // indirect
google.golang.org/grpc v1.83.2 // indirect
google.golang.org/grpc v1.84.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
Expand Down
112 changes: 56 additions & 56 deletions go.sum

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions internal/publisher/toolbar/toolbar.js

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions internal/publisher/visitorpolicy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (p *Policy) Refresh(ctx context.Context) error {
case <-call.Done():
return context.Cause(call)
}
if err := context.Cause(call); err != nil {
if err := refreshContextError(call); err != nil {
return err
}
request := p.Lease.Begin()
Expand All @@ -118,7 +118,7 @@ func (p *Policy) Refresh(ctx context.Context) error {
if err != nil {
return err
}
if err := call.Err(); err != nil {
if err := refreshContextError(call); err != nil {
return err
}
update, err := visitorlease.Decode(response)
Expand All @@ -128,6 +128,18 @@ func (p *Policy) Refresh(ctx context.Context) error {
return p.Lease.Apply(request, update)
}

// timer callbacks can lag their deadline. neither a newly acquired gate nor a
// late control response may spend that delay as additional preparation time.
func refreshContextError(ctx context.Context) error {
if err := context.Cause(ctx); err != nil {
return err
}
if deadline, ok := ctx.Deadline(); ok && !time.Now().Before(deadline) {
return context.DeadlineExceeded
}
return nil
}

func (p *Policy) Close() {
p.cancel()
<-p.done
Expand Down
51 changes: 51 additions & 0 deletions internal/publisher/visitorpolicy/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,57 @@ func TestPublisherVisitorPolicyWaitingRefreshIsCancelableAndBounded(t *testing.T
}
}

// model the interval after a deadline passes but before its timer callback runs.
// the embedded context still supplies cancellation and values normally.
type timerLagContext struct {
context.Context
deadline time.Time
}

func (c timerLagContext) Deadline() (time.Time, bool) { return c.deadline, true }

func TestPublisherVisitorPolicyAbsoluteDeadlineFencesTimerLag(t *testing.T) {
for _, lateResponse := range []bool{false, true} {
t.Run(map[bool]string{false: "before fetch", true: "control response"}[lateResponse], func(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
base := &policyClientFixture{key: ed25519.NewKeyFromSeed([]byte(strings.Repeat("p", 32)))}
client := startupPolicyClient(func(ctx context.Context, body controlv1.PublisherVisitorPolicyRequest, token string) (controlv1.VisitorPolicyUpdate, error) {
if base.calls.Load() > 0 && lateResponse {
time.Sleep(time.Second)
if ctx.Err() != nil {
t.Error("fixture did not retain the delayed timer callback")
}
}
return base.ReadPublisherVisitorPolicy(ctx, body, token)
})
scope := visitorscope.Scope{Kind: visitorscope.PublicURL, ID: "url_" + strings.Repeat("A", 22)}
policy, err := Prepare(t.Context(), client, scope, "run", 1, "run-secret", nil)
if err != nil {
t.Fatal(err)
}
defer policy.Close()
before, _, _ := policy.Lease.Current()
call := timerLagContext{Context: t.Context(), deadline: time.Now().Add(time.Second)}
wantCalls := int64(2)
if !lateResponse {
time.Sleep(time.Second)
wantCalls = 1
}
if err := policy.Refresh(call); !errors.Is(err, context.DeadlineExceeded) {
t.Error("refresh accepted an expired absolute deadline", err)
}
if base.calls.Load() != wantCalls {
t.Error("expired preparation issued another control call", base.calls.Load())
}
current, enabled, _ := policy.Lease.Current()
if !enabled || !current.ControlTime.Equal(before.ControlTime) || !current.ValidUntil.Equal(before.ValidUntil) {
t.Error("expired preparation installed a late observation")
}
})
})
}
}

func (f *policyClientFixture) ReadPublisherVisitorPolicy(_ context.Context, body controlv1.PublisherVisitorPolicyRequest, credential string) (controlv1.VisitorPolicyUpdate, error) {
f.calls.Add(1)
if credential != "run-secret" {
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@testing-library/preact": "3.2.4",
"@testing-library/user-event": "14.6.7",
"@types/jsdom": "30.0.0",
"@types/mysql": "2.15.27",
"@types/mysql": "2.15.28",
"@types/node": "22.20.5",
"@types/pg": "8.23.1",
"@types/react": "19.3.0",
Expand All @@ -38,12 +38,12 @@
"mysql": "2.18.1",
"mysql2": "3.24.6",
"openapi-types": "12.1.3",
"oxfmt": "0.71.0",
"oxlint": "1.86.0",
"oxfmt": "0.72.0",
"oxlint": "1.87.0",
"pg": "8.23.1",
"playwright": "1.63.0",
"playwright": "1.64.0",
"postgres": "3.4.9",
"preact": "11.0.0",
"preact": "11.0.1",
"react": "19.3.0",
"typed-openapi": "4.1.0",
"typescript": "7.0.2",
Expand Down
10 changes: 5 additions & 5 deletions packages/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@
"prepack": "pnpm run build"
},
"dependencies": {
"@opentelemetry/api": "1.9.0",
"@opentelemetry/api": "1.9.1",
"@vercel/oidc": "4.0.2",
"undici": "7.30.1",
"zod": "4.6.5"
},
"devDependencies": {
"@hono/node-server": "2.1.3",
"@hono/node-server": "2.1.4",
"@types/bun": "1.4.2",
"hono": "4.13.12",
"next": "16.3.8",
"hono": "4.13.13",
"next": "16.4.0",
"react": "19.3.0",
"react-dom": "19.3.0",
"vite": "8.3.3"
"vite": "8.3.4"
},
"peerDependencies": {
"next": ">=16.3.4",
Expand Down
Loading
Loading