From 33ebe51e01be2c94532ead8fdf090b724db817fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20S=CC=8Ctibrany=CC=81?= Date: Thu, 13 Feb 2020 10:34:35 +0100 Subject: [PATCH 1/5] Use go.uber.org/atomic, which is new module name for github.com/uber-go/atomic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Štibraný --- go.mod | 2 +- go.sum | 2 -- pkg/ring/kv/multi.go | 2 +- pkg/util/runtimeconfig/manager_test.go | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 872da55805a..3f247cd7477 100644 --- a/go.mod +++ b/go.mod @@ -61,12 +61,12 @@ require ( github.com/thanos-io/thanos v0.8.1-0.20200109203923-552ffa4c1a0d github.com/tinylib/msgp v0.0.0-20161221055906-38a6f61a768d // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect - github.com/uber-go/atomic v1.4.0 github.com/uber/jaeger-client-go v2.20.1+incompatible github.com/weaveworks/billing-client v0.0.0-20171006123215-be0d55e547b1 github.com/weaveworks/common v0.0.0-20200201141823-27e183090ab1 go.etcd.io/bbolt v1.3.3 go.etcd.io/etcd v0.0.0-20190709142735-eb7dd97135a5 + go.uber.org/atomic v1.5.0 golang.org/x/net v0.0.0-20191112182307-2180aed22343 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 google.golang.org/api v0.14.0 diff --git a/go.sum b/go.sum index a7c69ca9a4c..c96ae2c9604 100644 --- a/go.sum +++ b/go.sum @@ -763,8 +763,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o= -github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU= github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= diff --git a/pkg/ring/kv/multi.go b/pkg/ring/kv/multi.go index 11b4d68b2e5..fbbed83f794 100644 --- a/pkg/ring/kv/multi.go +++ b/pkg/ring/kv/multi.go @@ -9,11 +9,11 @@ import ( "github.com/go-kit/kit/log" "github.com/prometheus/client_golang/prometheus" + "go.uber.org/atomic" "github.com/cortexproject/cortex/pkg/util" "github.com/go-kit/kit/log/level" - "github.com/uber-go/atomic" ) var ( diff --git a/pkg/util/runtimeconfig/manager_test.go b/pkg/util/runtimeconfig/manager_test.go index 7a008af7f47..e72d734b237 100644 --- a/pkg/util/runtimeconfig/manager_test.go +++ b/pkg/util/runtimeconfig/manager_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/stretchr/testify/require" - "github.com/uber-go/atomic" + "go.uber.org/atomic" "gopkg.in/yaml.v2" ) From bf08c129a5d910081e817067d24526609d49bdc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20S=CC=8Ctibrany=CC=81?= Date: Thu, 13 Feb 2020 10:38:02 +0100 Subject: [PATCH 2/5] Stop() now tries to wait until messages generated via CAS are sent out. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Štibraný --- pkg/ring/kv/memberlist/memberlist_client.go | 62 +++++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/pkg/ring/kv/memberlist/memberlist_client.go b/pkg/ring/kv/memberlist/memberlist_client.go index 75e3f31e4dc..53a620a84de 100644 --- a/pkg/ring/kv/memberlist/memberlist_client.go +++ b/pkg/ring/kv/memberlist/memberlist_client.go @@ -15,6 +15,7 @@ import ( "github.com/go-kit/kit/log/level" "github.com/hashicorp/memberlist" "github.com/prometheus/client_golang/prometheus" + "go.uber.org/atomic" "github.com/cortexproject/cortex/pkg/ring/kv/codec" "github.com/cortexproject/cortex/pkg/util" @@ -120,6 +121,9 @@ type KV struct { memberlist *memberlist.Memberlist broadcasts *memberlist.TransmitLimitedQueue + // Disabled on Stop() + casBroadcastsEnabled *atomic.Bool + // KV Store. storeMu sync.Mutex store map[string]valueDesc @@ -224,17 +228,18 @@ func NewKV(cfg KVConfig) (*KV, error) { // As we don't use UDP for sending packets, we can use higher value here. mlCfg.UDPBufferSize = 10 * 1024 * 1024 - memberlistClient := &KV{ - cfg: cfg, - store: make(map[string]valueDesc), - codecs: make(map[string]codec.Codec), - watchers: make(map[string][]chan string), - prefixWatchers: make(map[string][]chan string), - shutdown: make(chan struct{}), - maxCasRetries: maxCasRetries, + mlkv := &KV{ + cfg: cfg, + store: make(map[string]valueDesc), + codecs: make(map[string]codec.Codec), + watchers: make(map[string][]chan string), + prefixWatchers: make(map[string][]chan string), + shutdown: make(chan struct{}), + maxCasRetries: maxCasRetries, + casBroadcastsEnabled: atomic.NewBool(true), } - mlCfg.Delegate = memberlistClient + mlCfg.Delegate = mlkv list, err := memberlist.Create(mlCfg) if err != nil { @@ -242,24 +247,24 @@ func NewKV(cfg KVConfig) (*KV, error) { } // finish delegate initialization - memberlistClient.memberlist = list - memberlistClient.broadcasts = &memberlist.TransmitLimitedQueue{ + mlkv.memberlist = list + mlkv.broadcasts = &memberlist.TransmitLimitedQueue{ NumNodes: list.NumMembers, RetransmitMult: cfg.RetransmitMult, } // Almost ready... - memberlistClient.createAndRegisterMetrics() + mlkv.createAndRegisterMetrics() for _, c := range cfg.Codecs { - memberlistClient.codecs[c.CodecID()] = c + mlkv.codecs[c.CodecID()] = c } // Join the cluster if len(cfg.JoinMembers) > 0 { - reached, err := memberlistClient.JoinMembers(cfg.JoinMembers) + reached, err := mlkv.JoinMembers(cfg.JoinMembers) if err != nil && cfg.AbortIfJoinFails { - _ = memberlistClient.memberlist.Shutdown() + _ = mlkv.memberlist.Shutdown() return nil, err } @@ -270,7 +275,7 @@ func NewKV(cfg KVConfig) (*KV, error) { } } - return memberlistClient, nil + return mlkv, nil } // GetCodec returns codec for given ID or nil. @@ -294,7 +299,23 @@ func (m *KV) JoinMembers(members []string) (int, error) { func (m *KV) Stop() { level.Info(util.Logger).Log("msg", "leaving memberlist cluster") - // TODO: should we empty our broadcast queue before leaving? That would make sure that we have sent out everything we wanted. + m.casBroadcastsEnabled.Store(false) + + // Wait until broadcast queue is empty, but don't wait for too long. + // Also don't wait if there is just one node left. + // Problem is that broadcast queue is also filled up by state changes received from other nodes, + // so it may never be empty in a busy cluster. However, we generally only care about messages + // generated on this node via CAS, and those are disabled now (via casBroadcastsEnabled), and should be able + // to get out in this timeout. + + waitTimeout := time.Now().Add(10 * time.Second) + for m.broadcasts.NumQueued() > 0 && m.memberlist.NumMembers() > 1 && time.Now().Before(waitTimeout) { + time.Sleep(250 * time.Millisecond) + } + + if cnt := m.broadcasts.NumQueued(); cnt > 0 { + level.Warn(util.Logger).Log("msg", "broadcast message left in queue", "count", cnt, "nodes", m.memberlist.NumMembers()) + } err := m.memberlist.Leave(m.cfg.LeaveTimeout) if err != nil { @@ -524,7 +545,12 @@ outer: if change != nil { m.casSuccesses.Inc() m.notifyWatchers(key) - m.broadcastNewValue(key, change, newver, codec) + + if m.casBroadcastsEnabled.Load() { + m.broadcastNewValue(key, change, newver, codec) + } else { + level.Error(util.Logger).Log("msg", "CAS with broadcasts disabled", "key", key) + } } return nil From a51baa3781bb27628085dfa5b08963f10cc406aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20S=CC=8Ctibrany=CC=81?= Date: Thu, 13 Feb 2020 10:38:43 +0100 Subject: [PATCH 3/5] Speed up state convergence to make test faster and avoid flakiness. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Štibraný --- integration/integration_memberlist_single_binary_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integration/integration_memberlist_single_binary_test.go b/integration/integration_memberlist_single_binary_test.go index 5cd8c787091..b435d589239 100644 --- a/integration/integration_memberlist_single_binary_test.go +++ b/integration/integration_memberlist_single_binary_test.go @@ -62,6 +62,7 @@ func startSingleBinary(s *framework.Scenario, name string, join string) error { "-ingester.observe-period": "5s", // to avoid conflicts in tokens "-ring.store": "memberlist", "-memberlist.bind-port": "8000", + "-memberlist.pullpush-interval": "3s", // speed up state convergence to make test faster and avoid flakiness } if join != "" { From 23c879f17bb344d5e8aca7d6ecce489f46788586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20S=CC=8Ctibrany=CC=81?= Date: Thu, 13 Feb 2020 10:47:18 +0100 Subject: [PATCH 4/5] =?UTF-8?q?git=20mod=20vendor=20Signed-off-by:=20Peter?= =?UTF-8?q?=20S=CC=8Ctibrany=CC=81=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/github.com/uber-go/atomic/.codecov.yml | 15 - vendor/github.com/uber-go/atomic/.gitignore | 11 - vendor/github.com/uber-go/atomic/.travis.yml | 27 -- vendor/github.com/uber-go/atomic/LICENSE.txt | 19 - vendor/github.com/uber-go/atomic/Makefile | 51 --- vendor/github.com/uber-go/atomic/README.md | 36 -- vendor/github.com/uber-go/atomic/atomic.go | 351 ------------------ vendor/github.com/uber-go/atomic/error.go | 55 --- vendor/github.com/uber-go/atomic/glide.lock | 17 - vendor/github.com/uber-go/atomic/glide.yaml | 6 - vendor/github.com/uber-go/atomic/string.go | 49 --- vendor/modules.txt | 2 - 12 files changed, 639 deletions(-) delete mode 100644 vendor/github.com/uber-go/atomic/.codecov.yml delete mode 100644 vendor/github.com/uber-go/atomic/.gitignore delete mode 100644 vendor/github.com/uber-go/atomic/.travis.yml delete mode 100644 vendor/github.com/uber-go/atomic/LICENSE.txt delete mode 100644 vendor/github.com/uber-go/atomic/Makefile delete mode 100644 vendor/github.com/uber-go/atomic/README.md delete mode 100644 vendor/github.com/uber-go/atomic/atomic.go delete mode 100644 vendor/github.com/uber-go/atomic/error.go delete mode 100644 vendor/github.com/uber-go/atomic/glide.lock delete mode 100644 vendor/github.com/uber-go/atomic/glide.yaml delete mode 100644 vendor/github.com/uber-go/atomic/string.go diff --git a/vendor/github.com/uber-go/atomic/.codecov.yml b/vendor/github.com/uber-go/atomic/.codecov.yml deleted file mode 100644 index 6d4d1be7b57..00000000000 --- a/vendor/github.com/uber-go/atomic/.codecov.yml +++ /dev/null @@ -1,15 +0,0 @@ -coverage: - range: 80..100 - round: down - precision: 2 - - status: - project: # measuring the overall project coverage - default: # context, you can create multiple ones with custom titles - enabled: yes # must be yes|true to enable this status - target: 100 # specify the target coverage for each commit status - # option: "auto" (must increase from parent commit or pull request base) - # option: "X%" a static target percentage to hit - if_not_found: success # if parent is not found report status as success, error, or failure - if_ci_failed: error # if ci fails report status as success, error, or failure - diff --git a/vendor/github.com/uber-go/atomic/.gitignore b/vendor/github.com/uber-go/atomic/.gitignore deleted file mode 100644 index 0a4504f1109..00000000000 --- a/vendor/github.com/uber-go/atomic/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.DS_Store -/vendor -/cover -cover.out -lint.log - -# Binaries -*.test - -# Profiling output -*.prof diff --git a/vendor/github.com/uber-go/atomic/.travis.yml b/vendor/github.com/uber-go/atomic/.travis.yml deleted file mode 100644 index 0f3769e5fa6..00000000000 --- a/vendor/github.com/uber-go/atomic/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -sudo: false -language: go -go_import_path: go.uber.org/atomic - -go: - - 1.11.x - - 1.12.x - -matrix: - include: - - go: 1.12.x - env: NO_TEST=yes LINT=yes - -cache: - directories: - - vendor - -install: - - make install_ci - -script: - - test -n "$NO_TEST" || make test_ci - - test -n "$NO_TEST" || scripts/test-ubergo.sh - - test -z "$LINT" || make install_lint lint - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/uber-go/atomic/LICENSE.txt b/vendor/github.com/uber-go/atomic/LICENSE.txt deleted file mode 100644 index 8765c9fbc61..00000000000 --- a/vendor/github.com/uber-go/atomic/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2016 Uber Technologies, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/uber-go/atomic/Makefile b/vendor/github.com/uber-go/atomic/Makefile deleted file mode 100644 index 1ef263075d7..00000000000 --- a/vendor/github.com/uber-go/atomic/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# Many Go tools take file globs or directories as arguments instead of packages. -PACKAGE_FILES ?= *.go - -# For pre go1.6 -export GO15VENDOREXPERIMENT=1 - - -.PHONY: build -build: - go build -i ./... - - -.PHONY: install -install: - glide --version || go get github.com/Masterminds/glide - glide install - - -.PHONY: test -test: - go test -cover -race ./... - - -.PHONY: install_ci -install_ci: install - go get github.com/wadey/gocovmerge - go get github.com/mattn/goveralls - go get golang.org/x/tools/cmd/cover - -.PHONY: install_lint -install_lint: - go get golang.org/x/lint/golint - - -.PHONY: lint -lint: - @rm -rf lint.log - @echo "Checking formatting..." - @gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log - @echo "Checking vet..." - @go vet ./... 2>&1 | tee -a lint.log;) - @echo "Checking lint..." - @golint $$(go list ./...) 2>&1 | tee -a lint.log - @echo "Checking for unresolved FIXMEs..." - @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log - @[ ! -s lint.log ] - - -.PHONY: test_ci -test_ci: install_ci build - ./scripts/cover.sh $(shell go list $(PACKAGES)) diff --git a/vendor/github.com/uber-go/atomic/README.md b/vendor/github.com/uber-go/atomic/README.md deleted file mode 100644 index 62eb8e57609..00000000000 --- a/vendor/github.com/uber-go/atomic/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard] - -Simple wrappers for primitive types to enforce atomic access. - -## Installation -`go get -u go.uber.org/atomic` - -## Usage -The standard library's `sync/atomic` is powerful, but it's easy to forget which -variables must be accessed atomically. `go.uber.org/atomic` preserves all the -functionality of the standard library, but wraps the primitive types to -provide a safer, more convenient API. - -```go -var atom atomic.Uint32 -atom.Store(42) -atom.Sub(2) -atom.CAS(40, 11) -``` - -See the [documentation][doc] for a complete API specification. - -## Development Status -Stable. - -___ -Released under the [MIT License](LICENSE.txt). - -[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg -[doc]: https://godoc.org/go.uber.org/atomic -[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master -[ci]: https://travis-ci.com/uber-go/atomic -[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg -[cov]: https://codecov.io/gh/uber-go/atomic -[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic -[reportcard]: https://goreportcard.com/report/go.uber.org/atomic diff --git a/vendor/github.com/uber-go/atomic/atomic.go b/vendor/github.com/uber-go/atomic/atomic.go deleted file mode 100644 index 1db6849fca0..00000000000 --- a/vendor/github.com/uber-go/atomic/atomic.go +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (c) 2016 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// Package atomic provides simple wrappers around numerics to enforce atomic -// access. -package atomic - -import ( - "math" - "sync/atomic" - "time" -) - -// Int32 is an atomic wrapper around an int32. -type Int32 struct{ v int32 } - -// NewInt32 creates an Int32. -func NewInt32(i int32) *Int32 { - return &Int32{i} -} - -// Load atomically loads the wrapped value. -func (i *Int32) Load() int32 { - return atomic.LoadInt32(&i.v) -} - -// Add atomically adds to the wrapped int32 and returns the new value. -func (i *Int32) Add(n int32) int32 { - return atomic.AddInt32(&i.v, n) -} - -// Sub atomically subtracts from the wrapped int32 and returns the new value. -func (i *Int32) Sub(n int32) int32 { - return atomic.AddInt32(&i.v, -n) -} - -// Inc atomically increments the wrapped int32 and returns the new value. -func (i *Int32) Inc() int32 { - return i.Add(1) -} - -// Dec atomically decrements the wrapped int32 and returns the new value. -func (i *Int32) Dec() int32 { - return i.Sub(1) -} - -// CAS is an atomic compare-and-swap. -func (i *Int32) CAS(old, new int32) bool { - return atomic.CompareAndSwapInt32(&i.v, old, new) -} - -// Store atomically stores the passed value. -func (i *Int32) Store(n int32) { - atomic.StoreInt32(&i.v, n) -} - -// Swap atomically swaps the wrapped int32 and returns the old value. -func (i *Int32) Swap(n int32) int32 { - return atomic.SwapInt32(&i.v, n) -} - -// Int64 is an atomic wrapper around an int64. -type Int64 struct{ v int64 } - -// NewInt64 creates an Int64. -func NewInt64(i int64) *Int64 { - return &Int64{i} -} - -// Load atomically loads the wrapped value. -func (i *Int64) Load() int64 { - return atomic.LoadInt64(&i.v) -} - -// Add atomically adds to the wrapped int64 and returns the new value. -func (i *Int64) Add(n int64) int64 { - return atomic.AddInt64(&i.v, n) -} - -// Sub atomically subtracts from the wrapped int64 and returns the new value. -func (i *Int64) Sub(n int64) int64 { - return atomic.AddInt64(&i.v, -n) -} - -// Inc atomically increments the wrapped int64 and returns the new value. -func (i *Int64) Inc() int64 { - return i.Add(1) -} - -// Dec atomically decrements the wrapped int64 and returns the new value. -func (i *Int64) Dec() int64 { - return i.Sub(1) -} - -// CAS is an atomic compare-and-swap. -func (i *Int64) CAS(old, new int64) bool { - return atomic.CompareAndSwapInt64(&i.v, old, new) -} - -// Store atomically stores the passed value. -func (i *Int64) Store(n int64) { - atomic.StoreInt64(&i.v, n) -} - -// Swap atomically swaps the wrapped int64 and returns the old value. -func (i *Int64) Swap(n int64) int64 { - return atomic.SwapInt64(&i.v, n) -} - -// Uint32 is an atomic wrapper around an uint32. -type Uint32 struct{ v uint32 } - -// NewUint32 creates a Uint32. -func NewUint32(i uint32) *Uint32 { - return &Uint32{i} -} - -// Load atomically loads the wrapped value. -func (i *Uint32) Load() uint32 { - return atomic.LoadUint32(&i.v) -} - -// Add atomically adds to the wrapped uint32 and returns the new value. -func (i *Uint32) Add(n uint32) uint32 { - return atomic.AddUint32(&i.v, n) -} - -// Sub atomically subtracts from the wrapped uint32 and returns the new value. -func (i *Uint32) Sub(n uint32) uint32 { - return atomic.AddUint32(&i.v, ^(n - 1)) -} - -// Inc atomically increments the wrapped uint32 and returns the new value. -func (i *Uint32) Inc() uint32 { - return i.Add(1) -} - -// Dec atomically decrements the wrapped int32 and returns the new value. -func (i *Uint32) Dec() uint32 { - return i.Sub(1) -} - -// CAS is an atomic compare-and-swap. -func (i *Uint32) CAS(old, new uint32) bool { - return atomic.CompareAndSwapUint32(&i.v, old, new) -} - -// Store atomically stores the passed value. -func (i *Uint32) Store(n uint32) { - atomic.StoreUint32(&i.v, n) -} - -// Swap atomically swaps the wrapped uint32 and returns the old value. -func (i *Uint32) Swap(n uint32) uint32 { - return atomic.SwapUint32(&i.v, n) -} - -// Uint64 is an atomic wrapper around a uint64. -type Uint64 struct{ v uint64 } - -// NewUint64 creates a Uint64. -func NewUint64(i uint64) *Uint64 { - return &Uint64{i} -} - -// Load atomically loads the wrapped value. -func (i *Uint64) Load() uint64 { - return atomic.LoadUint64(&i.v) -} - -// Add atomically adds to the wrapped uint64 and returns the new value. -func (i *Uint64) Add(n uint64) uint64 { - return atomic.AddUint64(&i.v, n) -} - -// Sub atomically subtracts from the wrapped uint64 and returns the new value. -func (i *Uint64) Sub(n uint64) uint64 { - return atomic.AddUint64(&i.v, ^(n - 1)) -} - -// Inc atomically increments the wrapped uint64 and returns the new value. -func (i *Uint64) Inc() uint64 { - return i.Add(1) -} - -// Dec atomically decrements the wrapped uint64 and returns the new value. -func (i *Uint64) Dec() uint64 { - return i.Sub(1) -} - -// CAS is an atomic compare-and-swap. -func (i *Uint64) CAS(old, new uint64) bool { - return atomic.CompareAndSwapUint64(&i.v, old, new) -} - -// Store atomically stores the passed value. -func (i *Uint64) Store(n uint64) { - atomic.StoreUint64(&i.v, n) -} - -// Swap atomically swaps the wrapped uint64 and returns the old value. -func (i *Uint64) Swap(n uint64) uint64 { - return atomic.SwapUint64(&i.v, n) -} - -// Bool is an atomic Boolean. -type Bool struct{ v uint32 } - -// NewBool creates a Bool. -func NewBool(initial bool) *Bool { - return &Bool{boolToInt(initial)} -} - -// Load atomically loads the Boolean. -func (b *Bool) Load() bool { - return truthy(atomic.LoadUint32(&b.v)) -} - -// CAS is an atomic compare-and-swap. -func (b *Bool) CAS(old, new bool) bool { - return atomic.CompareAndSwapUint32(&b.v, boolToInt(old), boolToInt(new)) -} - -// Store atomically stores the passed value. -func (b *Bool) Store(new bool) { - atomic.StoreUint32(&b.v, boolToInt(new)) -} - -// Swap sets the given value and returns the previous value. -func (b *Bool) Swap(new bool) bool { - return truthy(atomic.SwapUint32(&b.v, boolToInt(new))) -} - -// Toggle atomically negates the Boolean and returns the previous value. -func (b *Bool) Toggle() bool { - return truthy(atomic.AddUint32(&b.v, 1) - 1) -} - -func truthy(n uint32) bool { - return n&1 == 1 -} - -func boolToInt(b bool) uint32 { - if b { - return 1 - } - return 0 -} - -// Float64 is an atomic wrapper around float64. -type Float64 struct { - v uint64 -} - -// NewFloat64 creates a Float64. -func NewFloat64(f float64) *Float64 { - return &Float64{math.Float64bits(f)} -} - -// Load atomically loads the wrapped value. -func (f *Float64) Load() float64 { - return math.Float64frombits(atomic.LoadUint64(&f.v)) -} - -// Store atomically stores the passed value. -func (f *Float64) Store(s float64) { - atomic.StoreUint64(&f.v, math.Float64bits(s)) -} - -// Add atomically adds to the wrapped float64 and returns the new value. -func (f *Float64) Add(s float64) float64 { - for { - old := f.Load() - new := old + s - if f.CAS(old, new) { - return new - } - } -} - -// Sub atomically subtracts from the wrapped float64 and returns the new value. -func (f *Float64) Sub(s float64) float64 { - return f.Add(-s) -} - -// CAS is an atomic compare-and-swap. -func (f *Float64) CAS(old, new float64) bool { - return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new)) -} - -// Duration is an atomic wrapper around time.Duration -// https://godoc.org/time#Duration -type Duration struct { - v Int64 -} - -// NewDuration creates a Duration. -func NewDuration(d time.Duration) *Duration { - return &Duration{v: *NewInt64(int64(d))} -} - -// Load atomically loads the wrapped value. -func (d *Duration) Load() time.Duration { - return time.Duration(d.v.Load()) -} - -// Store atomically stores the passed value. -func (d *Duration) Store(n time.Duration) { - d.v.Store(int64(n)) -} - -// Add atomically adds to the wrapped time.Duration and returns the new value. -func (d *Duration) Add(n time.Duration) time.Duration { - return time.Duration(d.v.Add(int64(n))) -} - -// Sub atomically subtracts from the wrapped time.Duration and returns the new value. -func (d *Duration) Sub(n time.Duration) time.Duration { - return time.Duration(d.v.Sub(int64(n))) -} - -// Swap atomically swaps the wrapped time.Duration and returns the old value. -func (d *Duration) Swap(n time.Duration) time.Duration { - return time.Duration(d.v.Swap(int64(n))) -} - -// CAS is an atomic compare-and-swap. -func (d *Duration) CAS(old, new time.Duration) bool { - return d.v.CAS(int64(old), int64(new)) -} - -// Value shadows the type of the same name from sync/atomic -// https://godoc.org/sync/atomic#Value -type Value struct{ atomic.Value } diff --git a/vendor/github.com/uber-go/atomic/error.go b/vendor/github.com/uber-go/atomic/error.go deleted file mode 100644 index 0489d19badb..00000000000 --- a/vendor/github.com/uber-go/atomic/error.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2016 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package atomic - -// Error is an atomic type-safe wrapper around Value for errors -type Error struct{ v Value } - -// errorHolder is non-nil holder for error object. -// atomic.Value panics on saving nil object, so err object needs to be -// wrapped with valid object first. -type errorHolder struct{ err error } - -// NewError creates new atomic error object -func NewError(err error) *Error { - e := &Error{} - if err != nil { - e.Store(err) - } - return e -} - -// Load atomically loads the wrapped error -func (e *Error) Load() error { - v := e.v.Load() - if v == nil { - return nil - } - - eh := v.(errorHolder) - return eh.err -} - -// Store atomically stores error. -// NOTE: a holder object is allocated on each Store call. -func (e *Error) Store(err error) { - e.v.Store(errorHolder{err: err}) -} diff --git a/vendor/github.com/uber-go/atomic/glide.lock b/vendor/github.com/uber-go/atomic/glide.lock deleted file mode 100644 index 3c72c59976d..00000000000 --- a/vendor/github.com/uber-go/atomic/glide.lock +++ /dev/null @@ -1,17 +0,0 @@ -hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53 -updated: 2016-10-27T00:10:51.16960137-07:00 -imports: [] -testImports: -- name: github.com/davecgh/go-spew - version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d - subpackages: - - spew -- name: github.com/pmezard/go-difflib - version: d8ed2627bdf02c080bf22230dbb337003b7aba2d - subpackages: - - difflib -- name: github.com/stretchr/testify - version: d77da356e56a7428ad25149ca77381849a6a5232 - subpackages: - - assert - - require diff --git a/vendor/github.com/uber-go/atomic/glide.yaml b/vendor/github.com/uber-go/atomic/glide.yaml deleted file mode 100644 index 4cf608ec0f8..00000000000 --- a/vendor/github.com/uber-go/atomic/glide.yaml +++ /dev/null @@ -1,6 +0,0 @@ -package: go.uber.org/atomic -testImport: -- package: github.com/stretchr/testify - subpackages: - - assert - - require diff --git a/vendor/github.com/uber-go/atomic/string.go b/vendor/github.com/uber-go/atomic/string.go deleted file mode 100644 index ede8136face..00000000000 --- a/vendor/github.com/uber-go/atomic/string.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2016 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package atomic - -// String is an atomic type-safe wrapper around Value for strings. -type String struct{ v Value } - -// NewString creates a String. -func NewString(str string) *String { - s := &String{} - if str != "" { - s.Store(str) - } - return s -} - -// Load atomically loads the wrapped string. -func (s *String) Load() string { - v := s.v.Load() - if v == nil { - return "" - } - return v.(string) -} - -// Store atomically stores the passed string. -// Note: Converting the string to an interface{} to store in the Value -// requires an allocation. -func (s *String) Store(str string) { - s.v.Store(str) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index bd44c20b6ef..587b103f24f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -551,8 +551,6 @@ github.com/thanos-io/thanos/pkg/tracing github.com/tinylib/msgp/msgp # github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 github.com/tmc/grpc-websocket-proxy/wsproxy -# github.com/uber-go/atomic v1.4.0 -github.com/uber-go/atomic # github.com/uber/jaeger-client-go v2.20.1+incompatible github.com/uber/jaeger-client-go github.com/uber/jaeger-client-go/config From ee829884f9a6d7c24f6b30551b8cb3a610637fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20S=CC=8Ctibrany=CC=81?= Date: Thu, 13 Feb 2020 11:09:34 +0100 Subject: [PATCH 5/5] Review feedback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Štibraný --- pkg/ring/kv/memberlist/memberlist_client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/ring/kv/memberlist/memberlist_client.go b/pkg/ring/kv/memberlist/memberlist_client.go index 53a620a84de..c27b67ed098 100644 --- a/pkg/ring/kv/memberlist/memberlist_client.go +++ b/pkg/ring/kv/memberlist/memberlist_client.go @@ -314,7 +314,7 @@ func (m *KV) Stop() { } if cnt := m.broadcasts.NumQueued(); cnt > 0 { - level.Warn(util.Logger).Log("msg", "broadcast message left in queue", "count", cnt, "nodes", m.memberlist.NumMembers()) + level.Warn(util.Logger).Log("msg", "broadcast messages left in queue", "count", cnt, "nodes", m.memberlist.NumMembers()) } err := m.memberlist.Leave(m.cfg.LeaveTimeout) @@ -549,7 +549,7 @@ outer: if m.casBroadcastsEnabled.Load() { m.broadcastNewValue(key, change, newver, codec) } else { - level.Error(util.Logger).Log("msg", "CAS with broadcasts disabled", "key", key) + level.Warn(util.Logger).Log("msg", "skipped broadcasting CAS update because memberlist KV is shutting down", "key", key) } }