Skip to content

Commit

Permalink
Merge branch 'main' into infologging_ff_controls
Browse files Browse the repository at this point in the history
  • Loading branch information
PeSme committed Oct 8, 2024
2 parents 3508bde + 0a77019 commit e8e6c5d
Show file tree
Hide file tree
Showing 19 changed files with 1,886 additions and 2,354 deletions.
28 changes: 21 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -76,7 +82,8 @@ workflows:

release:
when:
not: << pipeline.parameters.rebuild_cache >>
and:
- not: << pipeline.parameters.rebuild_cache >>
jobs:
## <<Stencil::Block(circleWorkflowJobs)>>

Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
# you are reducing compatibility guarantees.
## <<Stencil::Block(toolverOverride)>>
## <</Stencil::Block>>
nodejs 18.17.1
golang 1.22.6
protoc 21.5
golang 1.21.5
nodejs 20.16.0
terraform 1.5.7
# Note: Versions in this block do not override the default versions above
# but sometimes you have to declare additional versions of the same tool
Expand Down
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"zxh404.vscode-proto3",
"redhat.vscode-yaml",
"ms-azuretools.vscode-docker",
"foxundermoon.shell-format"
"foxundermoon.shell-format",
"WizCloud.wizcli-vscode"

// Please consider contributing back all recommended
// extensions to stencil!
Expand Down
8 changes: 4 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
// Maps the go module cache on the host to the persistent volume used by devspaces.
// These should be the respective values of `go env GOMODCACHE`.
{
"from": "${env:HOME}/.asdf/installs/golang/1.21.5/packages/pkg/mod",
"to": "/home/dev/.asdf/installs/golang/1.21.5/packages/pkg/mod"
"from": "${env:HOME}/.asdf/installs/golang/1.22.6/packages/pkg/mod",
"to": "/home/dev/.asdf/installs/golang/1.22.6/packages/pkg/mod"
},
{
// Maps the standard library location on the host to the location in the devspace.
// This enables debugging standard library code.
"from": "${env:HOME}/.asdf/installs/golang/1.21.5/go/src",
"to": "/home/dev/.asdf/installs/golang/1.21.5/go/src"
"from": "${env:HOME}/.asdf/installs/golang/1.22.6/go/src",
"to": "/home/dev/.asdf/installs/golang/1.22.6/go/src"
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
APP := gobox
OSS := true
_ := $(shell ./scripts/devbase.sh)
_ := $(shell ./scripts/devbase.sh)

include .bootstrap/root/Makefile

Expand Down
14 changes: 7 additions & 7 deletions cortex.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ info:
repo: https://github.com/getoutreach/gobox
framework: stencil
language: Golang
stencil_version: v1.38.2-rc.1
golang_version: 1.21.5
stencil_version: v1.40.0-rc.1
golang_version: 1.22.6
cli: false
service: false
product: Outreach
Expand All @@ -56,8 +56,8 @@ info:
reporting_team: fnd-dt
lintroller: silver
x-cortex-groups:
- lifecycle: in_development
- product: Outreach
- language: Golang
- framework: stencil
- engOrg: fnd
- lifecycle:in_development
- product:Outreach
- language:Golang
- framework:stencil
- engOrg:fnd
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/getoutreach/gobox

go 1.21
go 1.22

toolchain go1.21.5
toolchain go1.22.6

require (
github.com/AlecAivazis/survey/v2 v2.3.7
Expand Down
4 changes: 3 additions & 1 deletion go.work
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 .

Expand Down
30 changes: 30 additions & 0 deletions go.work.sum

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
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"
}
}
70 changes: 70 additions & 0 deletions pkg/async/retryable_once.go
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
}
50 changes: 50 additions & 0 deletions pkg/async/retryable_once_retry_test.go
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'")
}
}
79 changes: 79 additions & 0 deletions pkg/async/retryable_once_test.go
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)
}
})
}
4 changes: 3 additions & 1 deletion pkg/ometrics/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/getoutreach/gobox/pkg/ometrics

go 1.21
go 1.22

toolchain go1.22.6

require (
github.com/getoutreach/gobox v1.85.0
Expand Down
Loading

0 comments on commit e8e6c5d

Please sign in to comment.