From 2a7207f38ace1a40e87330508cec9b4e6e26a59b Mon Sep 17 00:00:00 2001 From: hagen1778 <roman@victoriametrics.com> Date: Tue, 9 Jan 2024 13:17:09 +0100 Subject: [PATCH] app/all: follow-up after https://github.com/VictoriaMetrics/VictoriaMetrics/commit/84d710beab98067e88badbe4af4e0b523e2f6076 https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5548 Signed-off-by: hagen1778 <roman@victoriametrics.com> --- app/victoria-logs/main.go | 2 ++ app/vmagent/main.go | 1 + app/vmalert/main.go | 1 + app/vmauth/main.go | 1 + app/vmbackup/main.go | 1 + app/vminsert/main.go | 2 ++ app/vmrestore/main.go | 1 + app/vmselect/main.go | 2 ++ app/vmstorage/main.go | 4 +--- docs/CHANGELOG.md | 1 + lib/pushmetrics/pushmetrics.go | 14 +++++++++----- lib/uint64set/uint64set_test.go | 34 +++++++++++++++++++++++++++++++++ 12 files changed, 56 insertions(+), 8 deletions(-) diff --git a/app/victoria-logs/main.go b/app/victoria-logs/main.go index 5cf3add9a8..62d952c07a 100644 --- a/app/victoria-logs/main.go +++ b/app/victoria-logs/main.go @@ -59,6 +59,8 @@ func main() { } logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds()) + pushmetrics.Stop() + vlinsert.Stop() vlselect.Stop() vlstorage.Stop() diff --git a/app/vmagent/main.go b/app/vmagent/main.go index 9f66d54e8e..c681a84fae 100644 --- a/app/vmagent/main.go +++ b/app/vmagent/main.go @@ -159,6 +159,7 @@ func main() { logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds()) } + pushmetrics.Stop() promscrape.Stop() if len(*influxListenAddr) > 0 { diff --git a/app/vmalert/main.go b/app/vmalert/main.go index a87897204c..be8f0c1bde 100644 --- a/app/vmalert/main.go +++ b/app/vmalert/main.go @@ -187,6 +187,7 @@ func main() { if err := httpserver.Stop(*httpListenAddr); err != nil { logger.Fatalf("cannot stop the webservice: %s", err) } + pushmetrics.Stop() cancel() manager.close() } diff --git a/app/vmauth/main.go b/app/vmauth/main.go index b206619774..df9eeda007 100644 --- a/app/vmauth/main.go +++ b/app/vmauth/main.go @@ -80,6 +80,7 @@ func main() { if err := httpserver.Stop(*httpListenAddr); err != nil { logger.Fatalf("cannot stop the webservice: %s", err) } + pushmetrics.Stop() logger.Infof("successfully shut down the webservice in %.3f seconds", time.Since(startTime).Seconds()) stopAuthConfig() logger.Infof("successfully stopped vmauth in %.3f seconds", time.Since(startTime).Seconds()) diff --git a/app/vmbackup/main.go b/app/vmbackup/main.go index 40c5c8bf43..2ce83d476d 100644 --- a/app/vmbackup/main.go +++ b/app/vmbackup/main.go @@ -107,6 +107,7 @@ func main() { if err := httpserver.Stop(*httpListenAddr); err != nil { logger.Fatalf("cannot stop http server for metrics: %s", err) } + pushmetrics.Stop() logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds()) } diff --git a/app/vminsert/main.go b/app/vminsert/main.go index 6d6c4438c0..9c23117a51 100644 --- a/app/vminsert/main.go +++ b/app/vminsert/main.go @@ -161,6 +161,8 @@ func main() { } logger.Infof("successfully shut down http service in %.3f seconds", time.Since(startTime).Seconds()) + pushmetrics.Stop() + if len(*clusternativeListenAddr) > 0 { clusternativeServer.MustStop() } diff --git a/app/vmrestore/main.go b/app/vmrestore/main.go index cb2efcd79d..799d56ba7e 100644 --- a/app/vmrestore/main.go +++ b/app/vmrestore/main.go @@ -65,6 +65,7 @@ func main() { if err := httpserver.Stop(*httpListenAddr); err != nil { logger.Fatalf("cannot stop http server for metrics: %s", err) } + pushmetrics.Stop() logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds()) } diff --git a/app/vmselect/main.go b/app/vmselect/main.go index 52810d9b1a..268a45e62c 100644 --- a/app/vmselect/main.go +++ b/app/vmselect/main.go @@ -145,6 +145,8 @@ func main() { } logger.Infof("successfully shut down http service in %.3f seconds", time.Since(startTime).Seconds()) + pushmetrics.Stop() + if vmselectapiServer != nil { logger.Infof("stopping vmselectapi server...") vmselectapiServer.MustStop() diff --git a/app/vmstorage/main.go b/app/vmstorage/main.go index 8f9b0f9f5b..bf8c9cb90d 100644 --- a/app/vmstorage/main.go +++ b/app/vmstorage/main.go @@ -144,9 +144,7 @@ func main() { } logger.Infof("successfully shut down http service in %.3f seconds", time.Since(startTime).Seconds()) - // close the metric reporting goroutine - pushmetrics.StopPushMetrics() - logger.Infof("successfully stop push metric in %.3f seconds", time.Since(startTime).Seconds()) + pushmetrics.Stop() logger.Infof("gracefully shutting down the service") startTime = time.Now() diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e699b0cc94..67736c4e7f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -51,6 +51,7 @@ The sandbox cluster installation is running under the constant load generated by * BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): retry on import errors in `vm-native` mode. Before, retries happened only on writes into a network connection between source and destination. But errors returned by server after all the data was transmitted were logged, but not retried. * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly assume role with [AWS IRSA authorization](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). Previously role chaining was not supported. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3822) for details. * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix a link for the statistic inaccuracy explanation in the cardinality explorer tool. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5460). +* BUGFIX: all: fix potential panic during components shutdown when `-pushmetrics.url` is configured. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5548). Thanks to @zhdd99 for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5549). ## [v1.96.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.96.0) diff --git a/lib/pushmetrics/pushmetrics.go b/lib/pushmetrics/pushmetrics.go index 46d2be18e8..0e5ddff3f7 100644 --- a/lib/pushmetrics/pushmetrics.go +++ b/lib/pushmetrics/pushmetrics.go @@ -29,8 +29,7 @@ func init() { } var ( - // create a custom context for the pushmetrics module to close the metric reporting goroutine when the vmstorage process is shutdown. - pushMetricsCtx, cancelPushMetric = context.WithCancel(context.Background()) + pushCtx, cancelPushCtx = context.WithCancel(context.Background()) ) // Init must be called after logger.Init @@ -42,12 +41,17 @@ func Init() { Headers: *pushHeader, DisableCompression: *disableCompression, } - if err := metrics.InitPushExtWithOptions(pushMetricsCtx, pu, *pushInterval, appmetrics.WritePrometheusMetrics, opts); err != nil { + if err := metrics.InitPushExtWithOptions(pushCtx, pu, *pushInterval, appmetrics.WritePrometheusMetrics, opts); err != nil { logger.Fatalf("cannot initialize pushmetrics: %s", err) } } } -func StopPushMetrics() { - cancelPushMetric() +// Stop stops the periodic push of metrics. +// It is important to stop the push of metrics before disposing resources +// these metrics attached to. See related https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5548 +// +// Stop must be called after Init. +func Stop() { + cancelPushCtx() } diff --git a/lib/uint64set/uint64set_test.go b/lib/uint64set/uint64set_test.go index f6c7ed2794..7b027290c4 100644 --- a/lib/uint64set/uint64set_test.go +++ b/lib/uint64set/uint64set_test.go @@ -690,6 +690,40 @@ func testSetSparseItems(t *testing.T, itemsCount int) { } } +func FuzzAddMulti(f *testing.F) { + rand.Seed(time.Now().UnixNano()) + + f.Add(uint64(10)) + f.Fuzz(func(t *testing.T, v uint64) { + var s1, s2 Set + + v %= 1e3 + vs := make([]uint64, v) + for i := range vs { + vs[i] = rand.Uint64() + } + + s1.AddMulti(vs) + for _, v := range vs { + s2.Add(v) + } + if s1.Len() != s2.Len() { + t.Fatalf("unexpected number of items in the set; got %d; want %d\nset:\n%d", s1.Len(), s2.Len(), s1.AppendTo(nil)) + } + for _, x := range vs { + if !s1.Has(x) { + t.Fatalf("missing item %d in the set", x) + } + } + + a1 := s1.AppendTo(nil) + a2 := s2.AppendTo(nil) + if !reflect.DeepEqual(a1, a2) { + t.Fatalf("unexpected items in the set;\ngot\n%d\nwant\n%d", a1, a2) + } + }) +} + func TestAddMulti(t *testing.T) { f := func(a []uint64) { t.Helper()