-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into infologging_ff_controls
- Loading branch information
Showing
19 changed files
with
1,886 additions
and
2,354 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
|
@@ -2,13 +2,19 @@ | |
# syntax, such as anchors, will be fixed automatically. | ||
version: 2.1 | ||
orbs: | ||
shared: getoutreach/shared@2.25.1 | ||
shared: getoutreach/shared@2.28.1 | ||
queue: eddiewebb/[email protected] | ||
## <<Stencil::Block(CircleCIExtraOrbs)>> | ||
|
||
## <</Stencil::Block>> | ||
|
||
parameters: | ||
rebuild_cache: | ||
type: boolean | ||
default: false | ||
## <<Stencil::Block(CircleCIExtraParams)>> | ||
|
||
## <</Stencil::Block>> | ||
|
||
# Extra contexts to expose to all jobs below | ||
contexts: &contexts | ||
|
@@ -76,7 +82,8 @@ workflows: | |
|
||
release: | ||
when: | ||
not: << pipeline.parameters.rebuild_cache >> | ||
and: | ||
- not: << pipeline.parameters.rebuild_cache >> | ||
jobs: | ||
## <<Stencil::Block(circleWorkflowJobs)>> | ||
|
||
|
@@ -96,12 +103,19 @@ workflows: | |
- shared/test | ||
filters: | ||
branches: | ||
only: *release_branches | ||
|
||
# Dryrun release for PRs. | ||
- shared/release: | ||
<<: *release | ||
only: main | ||
# Dryrun for PRs | ||
- shared/pre-release: &pre-release | ||
dryrun: true | ||
context: *contexts | ||
## <<Stencil::Block(circlePreReleaseDryRunExtra)>> | ||
|
||
## <</Stencil::Block>> | ||
requires: | ||
## <<Stencil::Block(circlePreReleaseDryRunRequires)>> | ||
|
||
## <</Stencil::Block>> | ||
- shared/test | ||
filters: | ||
branches: | ||
ignore: *release_branches | ||
|
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -1,4 +1,6 @@ | ||
go 1.21 | ||
go 1.22 | ||
|
||
toolchain go1.22.6 | ||
|
||
use . | ||
|
||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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 |
---|---|---|
@@ -1,15 +1,15 @@ | ||
{ | ||
"license": "UNLICENSED", | ||
"devDependencies": { | ||
"@semantic-release/commit-analyzer": "^10.0.1", | ||
"@semantic-release/commit-analyzer": "^12.0.0", | ||
"@semantic-release/exec": "^6.0.3", | ||
"@semantic-release/git": "^10.0.1", | ||
"@semantic-release/github": "^9.0.3", | ||
"@semantic-release/npm": "^10.0.4", | ||
"@semantic-release/release-notes-generator": "^11.0.3", | ||
"conventional-changelog-conventionalcommits": "^6.0.0", | ||
"@semantic-release/github": "^10.0.3", | ||
"@semantic-release/npm": "^12.0.0", | ||
"@semantic-release/release-notes-generator": "^13.0.0", | ||
"conventional-changelog-conventionalcommits": "^7.0.2", | ||
"prettier": "^2.8.8", | ||
"semantic-release": "^21.0.5", | ||
"semver": "^7.5.2" | ||
"semantic-release": "^23.0.8", | ||
"semver": "^7.6.0" | ||
} | ||
} |
This file contains 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,70 @@ | ||
// Copyright 2024 Outreach Corporation. All Rights Reserved. | ||
|
||
// Description: implements RetryableOnce | ||
|
||
package async | ||
|
||
import ( | ||
"sync" | ||
"sync/atomic" | ||
) | ||
|
||
// RetryableOnce is modified from sync.Once with a tweak to allow retry | ||
type RetryableOnce struct { | ||
// done indicates whether the action has been performed. | ||
// It is first in the struct because it is used in the hot path. | ||
// The hot path is inlined at every call site. | ||
// Placing done first allows more compact instructions on some architectures (amd64/386), | ||
// and fewer instructions (to calculate offset) on other architectures. | ||
done atomic.Uint32 | ||
m sync.Mutex | ||
} | ||
|
||
// Do calls the function f if and only if one of the following of two cases | ||
// 1. Do is being called for the first time for this instance of RetryableOnce | ||
// 2. Do has been called multiple times before and f returns false in all those calls. | ||
// | ||
// If f panics, Do considers it as "done"; future calls of Do return | ||
// without calling f. | ||
// This function return true when future calls of Do will no longer call f | ||
func (o *RetryableOnce) Do(f func() bool) bool { | ||
// Note: Here is an incorrect implementation of Do: | ||
// | ||
// if o.done.CompareAndSwap(0, 1) { | ||
// f() | ||
// } | ||
// | ||
// Do guarantees that when it returns, f has finished. | ||
// This implementation would not implement that guarantee: | ||
// given two simultaneous calls, the winner of the cas would | ||
// call f, and the second would return immediately, without | ||
// waiting for the first's call to f to complete. | ||
// This is why the slow path falls back to a mutex, and why | ||
// the o.done.Store must be delayed until after f returns. | ||
|
||
if o.done.Load() == 0 { | ||
// Outlined slow-path to allow inlining of the fast-path. | ||
return o.doSlow(f) | ||
} | ||
return true | ||
} | ||
|
||
func (o *RetryableOnce) doSlow(f func() bool) bool { | ||
o.m.Lock() | ||
defer o.m.Unlock() | ||
if o.done.Load() == 0 { | ||
done := true | ||
defer func() { | ||
if done { | ||
// if f panic or return true, future calls of Do | ||
// return without calling f | ||
o.done.Store(1) | ||
} | ||
}() | ||
|
||
done = f() | ||
return done | ||
} | ||
|
||
return true | ||
} |
This file contains 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,50 @@ | ||
// Copyright 2024 Outreach Corporation. All Rights Reserved. | ||
// | ||
// Description: additional tests for verifying the retry behavior | ||
package async_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/getoutreach/gobox/pkg/async" | ||
) | ||
|
||
// TestOnceRetry verifies the retries behavior | ||
func TestOnceRetry(t *testing.T) { | ||
o := new(one) | ||
var once async.RetryableOnce | ||
|
||
result := once.Do(func() bool { | ||
o.Increment() | ||
return false | ||
}) | ||
if *o != 1 { | ||
t.Fatalf("Once.Do must be called once") | ||
} | ||
if result { | ||
t.Fatalf("Once.Do must return false to indicate 'not done'") | ||
} | ||
|
||
// This once.Do should still call the func since the first attempt requests a retry | ||
result = once.Do(func() bool { | ||
o.Increment() | ||
return true | ||
}) | ||
if *o != 2 { | ||
t.Fatalf("Once.Do must be called twice") | ||
} | ||
if !result { | ||
t.Fatalf("Once.Do must return true to indicate 'done'") | ||
} | ||
|
||
result = once.Do(func() bool { | ||
o.Increment() | ||
return false | ||
}) | ||
if *o != 2 { | ||
t.Fatalf("Once.Do must be called exactly twice") | ||
} | ||
if !result { | ||
t.Fatalf("Once.Do must return true to indicate 'done'") | ||
} | ||
} |
This file contains 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,79 @@ | ||
// Copyright 2024 Outreach Corporation. All Rights Reserved. | ||
// | ||
// Description: original sync.Once tests | ||
|
||
// Copyright 2009 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package async_test | ||
|
||
import ( | ||
// nolint: revive // Why: to minimize the manual edits which we have to make when copying from sync.Once | ||
. "github.com/getoutreach/gobox/pkg/async" | ||
|
||
"testing" | ||
) | ||
|
||
type one int | ||
|
||
func (o *one) Increment() { | ||
*o++ | ||
} | ||
|
||
func run(t *testing.T, once *RetryableOnce, o *one, c chan bool) { | ||
once.Do(func() bool { | ||
o.Increment() | ||
return true | ||
}) | ||
if v := *o; v != 1 { | ||
t.Errorf("once failed inside run: %d is not 1", v) | ||
} | ||
c <- true | ||
} | ||
|
||
func TestOnce(t *testing.T) { | ||
o := new(one) | ||
once := new(RetryableOnce) | ||
c := make(chan bool) | ||
const N = 10 | ||
for i := 0; i < N; i++ { | ||
go run(t, once, o, c) | ||
} | ||
for i := 0; i < N; i++ { | ||
<-c | ||
} | ||
if *o != 1 { | ||
t.Errorf("once failed outside run: %d is not 1", *o) | ||
} | ||
} | ||
|
||
func TestOncePanic(t *testing.T) { | ||
var once RetryableOnce | ||
func() { | ||
defer func() { | ||
if r := recover(); r == nil { | ||
t.Fatalf("Once.Do did not panic") | ||
} | ||
}() | ||
once.Do(func() bool { | ||
panic("failed") | ||
}) | ||
}() | ||
|
||
// panic can't be retried. This verifies that `once` is done after a panic | ||
once.Do(func() bool { | ||
t.Fatalf("Once.Do called twice") | ||
return true | ||
}) | ||
} | ||
|
||
func BenchmarkOnce(b *testing.B) { | ||
var once RetryableOnce | ||
f := func() bool { return true } | ||
b.RunParallel(func(pb *testing.PB) { | ||
for pb.Next() { | ||
once.Do(f) | ||
} | ||
}) | ||
} |
This file contains 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
Oops, something went wrong.