Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Chandler <wchandler@gitlab.com>2022-08-20 16:15:22 +0300
committerWill Chandler <wchandler@gitlab.com>2022-08-20 16:15:22 +0300
commit28b52c3b64fb857de6b1c62af662fe54249fa225 (patch)
treea637cef25392bedd1651349b64fb8ec922fbc412
parent109499970cae4fa648d9c0119bb708f0dd65f1d4 (diff)
parent72e1c78e920a917ae96a25271173740e6557888e (diff)
Merge branch 'renovate/github.com-pelletier-go-toml-2.x' into 'master'
go: Update module github.com/pelletier/go-toml to v2 See merge request gitlab-org/gitaly!4652
-rw-r--r--NOTICE230
-rw-r--r--cmd/gitaly/check_test.go2
-rw-r--r--cmd/gitaly/main.go2
-rw-r--r--cmd/praefect/main.go22
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--internal/blackbox/blackbox.go2
-rw-r--r--internal/blackbox/config.go7
-rw-r--r--internal/blackbox/config_test.go7
-rw-r--r--internal/gitaly/config/config.go35
-rw-r--r--internal/gitaly/config/config_test.go21
-rw-r--r--internal/gitaly/config/prometheus/config.go5
-rw-r--r--internal/gitaly/config/ruby.go24
-rw-r--r--internal/gitaly/maintenance/daily.go2
-rw-r--r--internal/gitaly/maintenance/daily_test.go3
-rw-r--r--internal/gitaly/rubyserver/rubyserver.go4
-rw-r--r--internal/helper/duration/duration.go28
-rw-r--r--internal/helper/duration/duration_test.go15
-rw-r--r--internal/middleware/limithandler/concurrency_limiter.go2
-rw-r--r--internal/middleware/limithandler/middleware_test.go3
-rw-r--r--internal/middleware/limithandler/rate_limiter.go2
-rw-r--r--internal/praefect/config/config.go51
-rw-r--r--internal/praefect/config/config_test.go47
-rw-r--r--internal/praefect/nodes/tracker/errors.go2
-rw-r--r--internal/streamcache/cache.go4
-rw-r--r--internal/streamcache/cache_test.go3
-rw-r--r--internal/testhelper/testserver/praefect.go2
27 files changed, 180 insertions, 349 deletions
diff --git a/NOTICE b/NOTICE
index f6b450f8b..2c380d9d1 100644
--- a/NOTICE
+++ b/NOTICE
@@ -19567,20 +19567,10 @@ LICENSE - github.com/opentracing/opentracing-go
limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LICENSE - github.com/pelletier/go-toml
-The bulk of github.com/pelletier/go-toml is distributed under the MIT license
-(see below), with the exception of localtime.go and localtime.test.go.
-Those two files have been copied over from Google's civil library at revision
-ed46f5086358513cf8c25f8e3f022cb838a49d66, and are distributed under the Apache
-2.0 license (see below).
-
-
-github.com/pelletier/go-toml:
-
-
+LICENSE - github.com/pelletier/go-toml/v2
The MIT License (MIT)
-Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton
+Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19600,222 +19590,6 @@ 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.
-
-localtime.go, localtime_test.go:
-
-Originals:
- https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil.go
- https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil_test.go
-Changes:
- * Renamed files from civil* to localtime*.
- * Package changed from civil to toml.
- * 'Local' prefix added to all structs.
-License:
- https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/LICENSE
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - github.com/pkg/errors
Copyright (c) 2015, Dave Cheney <dave@cheney.net>
diff --git a/cmd/gitaly/check_test.go b/cmd/gitaly/check_test.go
index f715b7661..19f5a3ea1 100644
--- a/cmd/gitaly/check_test.go
+++ b/cmd/gitaly/check_test.go
@@ -7,7 +7,7 @@ import (
"path/filepath"
"testing"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitlab"
diff --git a/cmd/gitaly/main.go b/cmd/gitaly/main.go
index a25932c6d..765d729ca 100644
--- a/cmd/gitaly/main.go
+++ b/cmd/gitaly/main.go
@@ -386,7 +386,7 @@ func run(cfg config.Cfg) error {
}
}()
- gracefulStopTicker := helper.NewTimerTicker(cfg.GracefulRestartTimeout)
+ gracefulStopTicker := helper.NewTimerTicker(cfg.GracefulRestartTimeout.Duration())
defer gracefulStopTicker.Stop()
return b.Wait(gracefulStopTicker, gitalyServerFactory.GracefulStop)
diff --git a/cmd/praefect/main.go b/cmd/praefect/main.go
index 1a434436c..76cb2071b 100644
--- a/cmd/praefect/main.go
+++ b/cmd/praefect/main.go
@@ -358,7 +358,7 @@ func run(
db,
nodeSet.Connections(),
hm,
- conf.BackgroundVerification.VerificationInterval,
+ conf.BackgroundVerification.VerificationInterval.Duration(),
conf.BackgroundVerification.DeleteInvalidRecords,
)
promreg.MustRegister(verifier)
@@ -394,7 +394,7 @@ func run(
primaryGetter = nodeMgr
nodeManager = nodeMgr
- nodeMgr.Start(conf.Failover.BootstrapInterval, conf.Failover.MonitorInterval)
+ nodeMgr.Start(conf.Failover.BootstrapInterval.Duration(), conf.Failover.MonitorInterval.Duration())
defer nodeMgr.Stop()
}
@@ -442,16 +442,16 @@ func run(
metricsCollectors = append(metricsCollectors, transactionManager, coordinator, repl)
if db != nil {
dbMetricCollectors := []prometheus.Collector{
- datastore.NewRepositoryStoreCollector(logger, conf.VirtualStorageNames(), db, conf.Prometheus.ScrapeTimeout),
- datastore.NewQueueDepthCollector(logger, db, conf.Prometheus.ScrapeTimeout),
+ datastore.NewRepositoryStoreCollector(logger, conf.VirtualStorageNames(), db, conf.Prometheus.ScrapeTimeout.Duration()),
+ datastore.NewQueueDepthCollector(logger, db, conf.Prometheus.ScrapeTimeout.Duration()),
}
if conf.BackgroundVerification.VerificationInterval > 0 {
dbMetricCollectors = append(dbMetricCollectors, datastore.NewVerificationQueueDepthCollector(
logger,
db,
- conf.Prometheus.ScrapeTimeout,
- conf.BackgroundVerification.VerificationInterval,
+ conf.Prometheus.ScrapeTimeout.Duration(),
+ conf.BackgroundVerification.VerificationInterval.Duration(),
conf.StorageNames(),
))
}
@@ -520,7 +520,7 @@ func run(
repl.ProcessStale(ctx, staleTicker, time.Minute)
logger.Info("background started: processing of the stale replication events")
- if interval := conf.Reconciliation.SchedulingInterval; interval > 0 {
+ if interval := conf.Reconciliation.SchedulingInterval.Duration(); interval > 0 {
if conf.MemoryQueueEnabled {
logger.Warn("Disabled automatic reconciliation as it is only implemented using SQL queue and in-memory queue is configured.")
} else {
@@ -540,17 +540,17 @@ func run(
}
}
- if interval := conf.RepositoriesCleanup.RunInterval; interval > 0 {
+ if interval := conf.RepositoriesCleanup.RunInterval.Duration(); interval > 0 {
if db != nil {
go func() {
storageSync := datastore.NewStorageCleanup(db)
cfg := repocleaner.Cfg{
- RunInterval: conf.RepositoriesCleanup.RunInterval,
+ RunInterval: conf.RepositoriesCleanup.RunInterval.Duration(),
LivenessInterval: 30 * time.Second,
RepositoriesInBatch: conf.RepositoriesCleanup.RepositoriesInBatch,
}
repoCleaner := repocleaner.NewRunner(cfg, logger, healthChecker, nodeSet.Connections(), storageSync, storageSync, repocleaner.NewLogWarnAction(logger))
- if err := repoCleaner.Run(ctx, helper.NewTimerTicker(conf.RepositoriesCleanup.CheckInterval)); err != nil && !errors.Is(context.Canceled, err) {
+ if err := repoCleaner.Run(ctx, helper.NewTimerTicker(conf.RepositoriesCleanup.CheckInterval.Duration())); err != nil && !errors.Is(context.Canceled, err) {
logger.WithError(err).Error("repository cleaner finished execution")
} else {
logger.Info("repository cleaner finished execution")
@@ -563,7 +563,7 @@ func run(
logger.Warn(`Repository cleanup background task disabled as "repositories_cleanup.run_interval" is not set or 0.`)
}
- gracefulStopTicker := helper.NewTimerTicker(conf.GracefulStopTimeout)
+ gracefulStopTicker := helper.NewTimerTicker(conf.GracefulStopTimeout.Duration())
defer gracefulStopTicker.Stop()
return b.Wait(gracefulStopTicker, srvFactory.GracefulStop)
diff --git a/go.mod b/go.mod
index e5ae2b314..bd047f26e 100644
--- a/go.mod
+++ b/go.mod
@@ -24,7 +24,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/runtime-spec v1.0.2
github.com/opentracing/opentracing-go v1.2.0
- github.com/pelletier/go-toml v1.9.5
+ github.com/pelletier/go-toml/v2 v2.0.3
github.com/prometheus/client_golang v1.12.2
github.com/prometheus/client_model v0.2.0
github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237
diff --git a/go.sum b/go.sum
index cad07c6e5..89aa25707 100644
--- a/go.sum
+++ b/go.sum
@@ -964,6 +964,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml/v2 v2.0.3 h1:h9JoA60e1dVEOpp0PFwJSmt1Htu057NUq9/bUwaO61s=
+github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
diff --git a/internal/blackbox/blackbox.go b/internal/blackbox/blackbox.go
index f793fdb0a..38cfa8b6d 100644
--- a/internal/blackbox/blackbox.go
+++ b/internal/blackbox/blackbox.go
@@ -138,7 +138,7 @@ func (b Blackbox) Run() error {
}
func (b Blackbox) runProbes() {
- for ; ; time.Sleep(b.cfg.sleepDuration) {
+ for ; ; time.Sleep(b.cfg.sleepDuration.Duration()) {
for _, probe := range b.cfg.Probes {
entry := log.Default().WithFields(map[string]interface{}{
"probe": probe.Name,
diff --git a/internal/blackbox/config.go b/internal/blackbox/config.go
index 4d8d373a5..9ea3c33a9 100644
--- a/internal/blackbox/config.go
+++ b/internal/blackbox/config.go
@@ -5,8 +5,9 @@ import (
"net/url"
"time"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
logconfig "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
// Config is the configuration for gitaly-blackbox.
@@ -17,7 +18,7 @@ type Config struct {
// Sleep is the number of seconds between probe runs.
Sleep int `toml:"sleep"`
// sleepDuration is the same as Sleep but converted to a proper duration.
- sleepDuration time.Duration
+ sleepDuration duration.Duration
// Logging configures logging.
Logging logconfig.Config `toml:"logging"`
// Probes defines endpoints to probe. At least one probe must be defined.
@@ -92,7 +93,7 @@ func ParseConfig(raw string) (Config, error) {
if config.Sleep == 0 {
config.Sleep = 15 * 60
}
- config.sleepDuration = time.Duration(config.Sleep) * time.Second
+ config.sleepDuration = duration.Duration(config.Sleep) * duration.Duration(time.Second)
if len(config.Probes) == 0 {
return Config{}, fmt.Errorf("must define at least one probe")
diff --git a/internal/blackbox/config_test.go b/internal/blackbox/config_test.go
index bdf80e165..6be4c80cc 100644
--- a/internal/blackbox/config_test.go
+++ b/internal/blackbox/config_test.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
func TestConfigParseFailures(t *testing.T) {
@@ -77,16 +78,16 @@ func TestConfigSleep(t *testing.T) {
testCases := []struct {
desc string
in string
- out time.Duration
+ out duration.Duration
}{
{
desc: "default sleep time",
- out: 15 * time.Minute,
+ out: duration.Duration(15 * time.Minute),
},
{
desc: "1 second",
in: "sleep = 1\n",
- out: time.Second,
+ out: duration.Duration(time.Second),
},
}
diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go
index c8988f77e..43fae6f40 100644
--- a/internal/gitaly/config/config.go
+++ b/internal/gitaly/config/config.go
@@ -13,13 +13,14 @@ import (
"syscall"
"time"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
log "github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups"
internallog "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
const (
@@ -32,10 +33,10 @@ const (
// DailyJob enables a daily task to be scheduled for specific storages
type DailyJob struct {
- Hour uint `toml:"start_hour"`
- Minute uint `toml:"start_minute"`
- Duration time.Duration `toml:"duration"`
- Storages []string `toml:"storages"`
+ Hour uint `toml:"start_hour"`
+ Minute uint `toml:"start_minute"`
+ Duration duration.Duration `toml:"duration"`
+ Storages []string `toml:"storages"`
// Disabled will completely disable a daily job, even in cases where a
// default schedule is implied
@@ -62,7 +63,7 @@ type Cfg struct {
Hooks Hooks `toml:"hooks"`
Concurrency []Concurrency `toml:"concurrency"`
RateLimiting []RateLimiting `toml:"rate_limiting"`
- GracefulRestartTimeout time.Duration `toml:"graceful_restart_timeout"`
+ GracefulRestartTimeout duration.Duration `toml:"graceful_restart_timeout"`
DailyMaintenance DailyJob `toml:"daily_maintenance"`
Cgroups cgroups.Config `toml:"cgroups"`
PackObjectsCache StreamCacheConfig `toml:"pack_objects_cache"`
@@ -147,7 +148,7 @@ type Concurrency struct {
MaxQueueSize int `toml:"max_queue_size"`
// MaxQueueWait is the maximum time a request can remain in the concurrency queue
// waiting to be picked up by Gitaly
- MaxQueueWait time.Duration `toml:"max_queue_wait"`
+ MaxQueueWait duration.Duration `toml:"max_queue_wait"`
}
// RateLimiting allows endpoints to be limited to a maximum request rate per
@@ -161,16 +162,16 @@ type RateLimiting struct {
RPC string `toml:"rpc"`
// Interval sets the interval with which the token bucket will
// be refilled to what is configured in Burst.
- Interval time.Duration `toml:"interval"`
+ Interval duration.Duration `toml:"interval"`
// Burst sets the capacity of the token bucket (see above).
Burst int `toml:"burst"`
}
// StreamCacheConfig contains settings for a streamcache instance.
type StreamCacheConfig struct {
- Enabled bool `toml:"enabled"` // Default: false
- Dir string `toml:"dir"` // Default: <FIRST STORAGE PATH>/+gitaly/PackObjectsCache
- MaxAge time.Duration `toml:"max_age"` // Default: 5m
+ Enabled bool `toml:"enabled"` // Default: false
+ Dir string `toml:"dir"` // Default: <FIRST STORAGE PATH>/+gitaly/PackObjectsCache
+ MaxAge duration.Duration `toml:"max_age"` // Default: 5m
}
// Load initializes the Config variable from file and the environment.
@@ -219,8 +220,8 @@ func (cfg *Cfg) Validate() error {
}
func (cfg *Cfg) setDefaults() error {
- if cfg.GracefulRestartTimeout == 0 {
- cfg.GracefulRestartTimeout = time.Minute
+ if cfg.GracefulRestartTimeout.Duration() == 0 {
+ cfg.GracefulRestartTimeout = duration.Duration(time.Minute)
}
if cfg.Gitlab.SecretFile == "" {
@@ -462,7 +463,7 @@ func defaultMaintenanceWindow(storages []Storage) DailyJob {
return DailyJob{
Hour: 12,
Minute: 0,
- Duration: 10 * time.Minute,
+ Duration: duration.Duration(10 * time.Minute),
Storages: storageNames,
}
}
@@ -486,8 +487,8 @@ func (cfg *Cfg) validateMaintenance() error {
if dm.Minute > 59 {
return fmt.Errorf("daily maintenance specified minute '%d' outside range (0-59)", dm.Minute)
}
- if dm.Duration > 24*time.Hour {
- return fmt.Errorf("daily maintenance specified duration %s must be less than 24 hours", dm.Duration)
+ if dm.Duration.Duration() > 24*time.Hour {
+ return fmt.Errorf("daily maintenance specified duration %s must be less than 24 hours", dm.Duration.Duration())
}
return nil
@@ -524,7 +525,7 @@ func (cfg *Cfg) configurePackObjectsCache() error {
}
if poc.MaxAge == 0 {
- poc.MaxAge = 5 * time.Minute
+ poc.MaxAge = duration.Duration(5 * time.Minute)
}
if poc.Dir == "" {
diff --git a/internal/gitaly/config/config_test.go b/internal/gitaly/config/config_test.go
index 0bc386636..fb93676f8 100644
--- a/internal/gitaly/config/config_test.go
+++ b/internal/gitaly/config/config_test.go
@@ -19,6 +19,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/cgroups"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
)
@@ -158,7 +159,7 @@ func TestLoadPrometheus(t *testing.T) {
require.Equal(t, ":9236", cfg.PrometheusListenAddr)
require.Equal(t, prometheus.Config{
- ScrapeTimeout: time.Second,
+ ScrapeTimeout: duration.Duration(time.Second),
GRPCLatencyBuckets: []float64{0, 1, 2},
}, cfg.Prometheus)
}
@@ -576,16 +577,16 @@ func TestLoadGracefulRestartTimeout(t *testing.T) {
tests := []struct {
name string
config string
- expected time.Duration
+ expected duration.Duration
}{
{
name: "default value",
- expected: 1 * time.Minute,
+ expected: duration.Duration(1 * time.Minute),
},
{
name: "8m03s",
config: `graceful_restart_timeout = "8m03s"`,
- expected: 8*time.Minute + 3*time.Second,
+ expected: duration.Duration(8*time.Minute + 3*time.Second),
},
}
for _, test := range tests {
@@ -715,7 +716,7 @@ func TestLoadDailyMaintenance(t *testing.T) {
expect: DailyJob{
Hour: 11,
Minute: 23,
- Duration: 45 * time.Minute,
+ Duration: duration.Duration(45 * time.Minute),
Storages: []string{"default"},
},
},
@@ -753,7 +754,7 @@ func TestLoadDailyMaintenance(t *testing.T) {
expect: DailyJob{
Hour: 0,
Minute: 59,
- Duration: 24*time.Hour + time.Second,
+ Duration: duration.Duration(24*time.Hour + time.Second),
},
validateErr: errors.New("daily maintenance specified duration 24h0m1s must be less than 24 hours"),
},
@@ -761,7 +762,7 @@ func TestLoadDailyMaintenance(t *testing.T) {
rawCfg: `[daily_maintenance]
duration = "meow"`,
expect: DailyJob{},
- loadErr: errors.New(`load toml: (2, 4): Can't convert meow(string) to time.Duration. time: invalid duration "meow"`),
+ loadErr: errors.New("load toml: toml: time: invalid duration \"meow\""),
},
{
rawCfg: `[daily_maintenance]
@@ -780,7 +781,7 @@ func TestLoadDailyMaintenance(t *testing.T) {
expect: DailyJob{
Hour: 12,
Minute: 0,
- Duration: 10 * time.Minute,
+ Duration: duration.Duration(10 * time.Minute),
Storages: []string{"default"},
},
},
@@ -1127,7 +1128,7 @@ path="/foobar"
in: storageConfig + `[pack_objects_cache]
enabled = true
`,
- out: StreamCacheConfig{Enabled: true, MaxAge: 5 * time.Minute, Dir: "/foobar/+gitaly/PackObjectsCache"},
+ out: StreamCacheConfig{Enabled: true, MaxAge: duration.Duration(5 * time.Minute), Dir: "/foobar/+gitaly/PackObjectsCache"},
},
{
desc: "enabled with custom values",
@@ -1136,7 +1137,7 @@ enabled = true
dir = "/bazqux"
max_age = "10m"
`,
- out: StreamCacheConfig{Enabled: true, MaxAge: 10 * time.Minute, Dir: "/bazqux"},
+ out: StreamCacheConfig{Enabled: true, MaxAge: duration.Duration(10 * time.Minute), Dir: "/bazqux"},
},
{
desc: "enabled with 0 storages",
diff --git a/internal/gitaly/config/prometheus/config.go b/internal/gitaly/config/prometheus/config.go
index 4873eec1d..12fbeec09 100644
--- a/internal/gitaly/config/prometheus/config.go
+++ b/internal/gitaly/config/prometheus/config.go
@@ -6,12 +6,13 @@ import (
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
// Config contains additional configuration data for prometheus
type Config struct {
// ScrapeTimeout is the allowed duration of a Prometheus scrape before timing out.
- ScrapeTimeout time.Duration `toml:"scrape_timeout,omitempty"`
+ ScrapeTimeout duration.Duration `toml:"scrape_timeout,omitempty"`
// GRPCLatencyBuckets configures the histogram buckets used for gRPC
// latency measurements.
GRPCLatencyBuckets []float64 `toml:"grpc_latency_buckets,omitempty"`
@@ -20,7 +21,7 @@ type Config struct {
// DefaultConfig returns a new config with default values set.
func DefaultConfig() Config {
return Config{
- ScrapeTimeout: 10 * time.Second,
+ ScrapeTimeout: duration.Duration(10 * time.Second),
GRPCLatencyBuckets: []float64{0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0},
}
}
diff --git a/internal/gitaly/config/ruby.go b/internal/gitaly/config/ruby.go
index 0392a31d7..92fa70c60 100644
--- a/internal/gitaly/config/ruby.go
+++ b/internal/gitaly/config/ruby.go
@@ -4,31 +4,33 @@ import (
"fmt"
"path/filepath"
"time"
+
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
// Ruby contains setting for Ruby worker processes
type Ruby struct {
- Dir string `toml:"dir"`
- MaxRSS int `toml:"max_rss"`
- GracefulRestartTimeout time.Duration `toml:"graceful_restart_timeout"`
- RestartDelay time.Duration `toml:"restart_delay"`
- NumWorkers int `toml:"num_workers"`
- LinguistLanguagesPath string `toml:"linguist_languages_path"`
- RuggedGitConfigSearchPath string `toml:"rugged_git_config_search_path"`
+ Dir string `toml:"dir"`
+ MaxRSS int `toml:"max_rss"`
+ GracefulRestartTimeout duration.Duration `toml:"graceful_restart_timeout"`
+ RestartDelay duration.Duration `toml:"restart_delay"`
+ NumWorkers int `toml:"num_workers"`
+ LinguistLanguagesPath string `toml:"linguist_languages_path"`
+ RuggedGitConfigSearchPath string `toml:"rugged_git_config_search_path"`
}
// ConfigureRuby validates the gitaly-ruby configuration and sets default values.
func (cfg *Cfg) ConfigureRuby() error {
- if cfg.Ruby.GracefulRestartTimeout == 0 {
- cfg.Ruby.GracefulRestartTimeout = 10 * time.Minute
+ if cfg.Ruby.GracefulRestartTimeout.Duration() == 0 {
+ cfg.Ruby.GracefulRestartTimeout = duration.Duration(10 * time.Minute)
}
if cfg.Ruby.MaxRSS == 0 {
cfg.Ruby.MaxRSS = 200 * 1024 * 1024
}
- if cfg.Ruby.RestartDelay == 0 {
- cfg.Ruby.RestartDelay = 5 * time.Minute
+ if cfg.Ruby.RestartDelay.Duration() == 0 {
+ cfg.Ruby.RestartDelay = duration.Duration(5 * time.Minute)
}
if len(cfg.Ruby.Dir) == 0 {
diff --git a/internal/gitaly/maintenance/daily.go b/internal/gitaly/maintenance/daily.go
index 93f00df2f..c99eeb547 100644
--- a/internal/gitaly/maintenance/daily.go
+++ b/internal/gitaly/maintenance/daily.go
@@ -61,7 +61,7 @@ func (dw DailyWorker) StartDaily(ctx context.Context, l logrus.FieldLogger, sche
var jobErr error
dontpanic.Try(func() {
- ctx, cancel := context.WithTimeout(ctx, schedule.Duration)
+ ctx, cancel := context.WithTimeout(ctx, schedule.Duration.Duration())
defer cancel()
jobErr = job(ctx, l, schedule.Storages)
diff --git a/internal/gitaly/maintenance/daily_test.go b/internal/gitaly/maintenance/daily_test.go
index ef43fbd54..689052e67 100644
--- a/internal/gitaly/maintenance/daily_test.go
+++ b/internal/gitaly/maintenance/daily_test.go
@@ -10,6 +10,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
)
@@ -37,7 +38,7 @@ func TestStartDaily(t *testing.T) {
errQ := make(chan error)
s := config.DailyJob{
Hour: 1,
- Duration: time.Hour,
+ Duration: duration.Duration(time.Hour),
Storages: []string{"meow"},
}
ctx, cancel := context.WithCancel(testhelper.Context(t))
diff --git a/internal/gitaly/rubyserver/rubyserver.go b/internal/gitaly/rubyserver/rubyserver.go
index 6bda8bdae..76c901a84 100644
--- a/internal/gitaly/rubyserver/rubyserver.go
+++ b/internal/gitaly/rubyserver/rubyserver.go
@@ -200,8 +200,8 @@ func (s *Server) start() error {
return err
}
- restartDelay := cfg.Ruby.RestartDelay
- gracefulRestartTimeout := cfg.Ruby.GracefulRestartTimeout
+ restartDelay := cfg.Ruby.RestartDelay.Duration()
+ gracefulRestartTimeout := cfg.Ruby.GracefulRestartTimeout.Duration()
s.workers = append(s.workers, newWorker(p, socketPath, restartDelay, gracefulRestartTimeout, events, false))
}
diff --git a/internal/helper/duration/duration.go b/internal/helper/duration/duration.go
new file mode 100644
index 000000000..5d1e5b87d
--- /dev/null
+++ b/internal/helper/duration/duration.go
@@ -0,0 +1,28 @@
+package duration
+
+import "time"
+
+// Duration is a trick to let our TOML library parse durations from strings.
+type Duration time.Duration
+
+// Duration converts the duration.Duration to a time.Duration
+func (d *Duration) Duration() time.Duration {
+ if d != nil {
+ return time.Duration(*d)
+ }
+ return 0
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface
+func (d *Duration) UnmarshalText(text []byte) error {
+ td, err := time.ParseDuration(string(text))
+ if err == nil {
+ *d = Duration(td)
+ }
+ return err
+}
+
+// MarshalText implements the encoding.TextMarshaler interface
+func (d Duration) MarshalText() ([]byte, error) {
+ return []byte(time.Duration(d).String()), nil
+}
diff --git a/internal/helper/duration/duration_test.go b/internal/helper/duration/duration_test.go
new file mode 100644
index 000000000..9ca1830dc
--- /dev/null
+++ b/internal/helper/duration/duration_test.go
@@ -0,0 +1,15 @@
+package duration
+
+import (
+ "encoding"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestDuration(t *testing.T) {
+ t.Parallel()
+
+ require.Implements(t, (*encoding.TextMarshaler)(nil), new(Duration))
+ require.Implements(t, (*encoding.TextUnmarshaler)(nil), new(Duration))
+}
diff --git a/internal/middleware/limithandler/concurrency_limiter.go b/internal/middleware/limithandler/concurrency_limiter.go
index cf552917d..e2595571b 100644
--- a/internal/middleware/limithandler/concurrency_limiter.go
+++ b/internal/middleware/limithandler/concurrency_limiter.go
@@ -276,7 +276,7 @@ func WithConcurrencyLimiters(cfg config.Cfg, middleware *LimiterMiddleware) {
if limit.MaxQueueWait > 0 {
limit := limit
newTickerFunc = func() helper.Ticker {
- return helper.NewTimerTicker(limit.MaxQueueWait)
+ return helper.NewTimerTicker(limit.MaxQueueWait.Duration())
}
}
diff --git a/internal/middleware/limithandler/middleware_test.go b/internal/middleware/limithandler/middleware_test.go
index 9a2fb9870..d5aa4ee57 100644
--- a/internal/middleware/limithandler/middleware_test.go
+++ b/internal/middleware/limithandler/middleware_test.go
@@ -16,6 +16,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v15/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
"gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler"
pb "gitlab.com/gitlab-org/gitaly/v15/internal/middleware/limithandler/testdata"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
@@ -487,7 +488,7 @@ func TestRateLimitHandler(t *testing.T) {
methodName := "/test.limithandler.Test/Unary"
cfg := config.Cfg{
RateLimiting: []config.RateLimiting{
- {RPC: methodName, Interval: 1 * time.Hour, Burst: 1},
+ {RPC: methodName, Interval: duration.Duration(1 * time.Hour), Burst: 1},
},
}
diff --git a/internal/middleware/limithandler/rate_limiter.go b/internal/middleware/limithandler/rate_limiter.go
index 89f6deeab..5f2f2d9f6 100644
--- a/internal/middleware/limithandler/rate_limiter.go
+++ b/internal/middleware/limithandler/rate_limiter.go
@@ -119,7 +119,7 @@ func WithRateLimiters(ctx context.Context) SetupFunc {
if limitCfg.Burst > 0 && limitCfg.Interval > 0 {
serviceName, methodName := splitMethodName(limitCfg.RPC)
rateLimiter := NewRateLimiter(
- limitCfg.Interval,
+ limitCfg.Interval.Duration(),
limitCfg.Burst,
helper.NewTimerTicker(5*time.Minute),
middleware.requestsDroppedMetric.With(prometheus.Labels{
diff --git a/internal/praefect/config/config.go b/internal/praefect/config/config.go
index 59a0f2be2..5af6eccdb 100644
--- a/internal/praefect/config/config.go
+++ b/internal/praefect/config/config.go
@@ -6,13 +6,14 @@ import (
"os"
"time"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
promclient "github.com/prometheus/client_golang/prometheus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
// ElectionStrategy is a Praefect primary election strategy.
@@ -44,16 +45,16 @@ const (
type Failover struct {
Enabled bool `toml:"enabled,omitempty"`
// ElectionStrategy is the strategy to use for electing primaries nodes.
- ElectionStrategy ElectionStrategy `toml:"election_strategy,omitempty"`
- ErrorThresholdWindow time.Duration `toml:"error_threshold_window,omitempty"`
- WriteErrorThresholdCount uint32 `toml:"write_error_threshold_count,omitempty"`
- ReadErrorThresholdCount uint32 `toml:"read_error_threshold_count,omitempty"`
+ ElectionStrategy ElectionStrategy `toml:"election_strategy,omitempty"`
+ ErrorThresholdWindow duration.Duration `toml:"error_threshold_window,omitempty"`
+ WriteErrorThresholdCount uint32 `toml:"write_error_threshold_count,omitempty"`
+ ReadErrorThresholdCount uint32 `toml:"read_error_threshold_count,omitempty"`
// BootstrapInterval allows set a time duration that would be used on startup to make initial health check.
// The default value is 1s.
- BootstrapInterval time.Duration `toml:"bootstrap_interval,omitempty"`
+ BootstrapInterval duration.Duration `toml:"bootstrap_interval,omitempty"`
// MonitorInterval allows set a time duration that would be used after bootstrap is completed to execute health checks.
// The default value is 3s.
- MonitorInterval time.Duration `toml:"monitor_interval,omitempty"`
+ MonitorInterval duration.Duration `toml:"monitor_interval,omitempty"`
}
// ErrorThresholdsConfigured checks whether returns whether the errors thresholds are configured. If they
@@ -82,7 +83,7 @@ func (f Failover) ErrorThresholdsConfigured() (bool, error) {
type BackgroundVerification struct {
// VerificationInterval determines the duration after a replica due for reverification.
// The feature is disabled if verification interval is 0 or below.
- VerificationInterval time.Duration `toml:"verification_interval,omitempty"`
+ VerificationInterval duration.Duration `toml:"verification_interval,omitempty"`
// DeleteInvalidRecords controls whether the background verifier will actually delete the metadata
// records that point to non-existent replicas.
DeleteInvalidRecords bool `toml:"delete_invalid_records"`
@@ -90,14 +91,14 @@ type BackgroundVerification struct {
// DefaultBackgroundVerificationConfig returns the default background verification configuration.
func DefaultBackgroundVerificationConfig() BackgroundVerification {
- return BackgroundVerification{VerificationInterval: 7 * 24 * time.Hour}
+ return BackgroundVerification{VerificationInterval: duration.Duration(7 * 24 * time.Hour)}
}
// Reconciliation contains reconciliation specific configuration options.
type Reconciliation struct {
// SchedulingInterval the interval between each automatic reconciliation run. If set to 0,
// automatic reconciliation is disabled.
- SchedulingInterval time.Duration `toml:"scheduling_interval,omitempty"`
+ SchedulingInterval duration.Duration `toml:"scheduling_interval,omitempty"`
// HistogramBuckets configures the reconciliation scheduling duration histogram's buckets.
HistogramBuckets []float64 `toml:"histogram_buckets,omitempty"`
}
@@ -105,7 +106,7 @@ type Reconciliation struct {
// DefaultReconciliationConfig returns the default values for reconciliation configuration.
func DefaultReconciliationConfig() Reconciliation {
return Reconciliation{
- SchedulingInterval: 5 * time.Minute,
+ SchedulingInterval: 5 * duration.Duration(time.Minute),
HistogramBuckets: promclient.DefBuckets,
}
}
@@ -152,7 +153,7 @@ type Config struct {
// Keep for legacy reasons: remove after Omnibus has switched
FailoverEnabled bool `toml:"failover_enabled,omitempty"`
MemoryQueueEnabled bool `toml:"memory_queue_enabled,omitempty"`
- GracefulStopTimeout time.Duration `toml:"graceful_stop_timeout,omitempty"`
+ GracefulStopTimeout duration.Duration `toml:"graceful_stop_timeout,omitempty"`
RepositoriesCleanup RepositoriesCleanup `toml:"repositories_cleanup,omitempty"`
}
@@ -276,11 +277,11 @@ func (c *Config) Validate() error {
}
}
- if c.RepositoriesCleanup.RunInterval > 0 {
- if c.RepositoriesCleanup.CheckInterval < minimalSyncCheckInterval {
+ if c.RepositoriesCleanup.RunInterval.Duration() > 0 {
+ if c.RepositoriesCleanup.CheckInterval.Duration() < minimalSyncCheckInterval {
return fmt.Errorf("repositories_cleanup.check_interval is less then %s, which could lead to a database performance problem", minimalSyncCheckInterval.String())
}
- if c.RepositoriesCleanup.RunInterval < minimalSyncRunInterval {
+ if c.RepositoriesCleanup.RunInterval.Duration() < minimalSyncRunInterval {
return fmt.Errorf("repositories_cleanup.run_interval is less then %s, which could lead to a database performance problem", minimalSyncRunInterval.String())
}
}
@@ -294,17 +295,17 @@ func (c *Config) NeedsSQL() bool {
}
func (c *Config) setDefaults() {
- if c.GracefulStopTimeout == 0 {
- c.GracefulStopTimeout = time.Minute
+ if c.GracefulStopTimeout.Duration() == 0 {
+ c.GracefulStopTimeout = duration.Duration(time.Minute)
}
if c.Failover.Enabled {
- if c.Failover.BootstrapInterval == 0 {
- c.Failover.BootstrapInterval = time.Second
+ if c.Failover.BootstrapInterval.Duration() == 0 {
+ c.Failover.BootstrapInterval = duration.Duration(time.Second)
}
- if c.Failover.MonitorInterval == 0 {
- c.Failover.MonitorInterval = 3 * time.Second
+ if c.Failover.MonitorInterval.Duration() == 0 {
+ c.Failover.MonitorInterval = duration.Duration(3 * time.Second)
}
}
}
@@ -383,9 +384,9 @@ type RepositoriesCleanup struct {
// CheckInterval is a time period used to check if operation should be executed.
// It is recommended to keep it less than run_interval configuration as some
// nodes may be out of service, so they can be stale for too long.
- CheckInterval time.Duration `toml:"check_interval,omitempty"`
+ CheckInterval duration.Duration `toml:"check_interval,omitempty"`
// RunInterval: the check runs if the previous operation was done at least RunInterval before.
- RunInterval time.Duration `toml:"run_interval,omitempty"`
+ RunInterval duration.Duration `toml:"run_interval,omitempty"`
// RepositoriesInBatch is the number of repositories to pass as a batch for processing.
RepositoriesInBatch int `toml:"repositories_in_batch,omitempty"`
}
@@ -393,8 +394,8 @@ type RepositoriesCleanup struct {
// DefaultRepositoriesCleanup contains default configuration values for the RepositoriesCleanup.
func DefaultRepositoriesCleanup() RepositoriesCleanup {
return RepositoriesCleanup{
- CheckInterval: 30 * time.Minute,
- RunInterval: 24 * time.Hour,
+ CheckInterval: duration.Duration(30 * time.Minute),
+ RunInterval: duration.Duration(24 * time.Hour),
RepositoriesInBatch: 16,
}
}
diff --git a/internal/praefect/config/config_test.go b/internal/praefect/config/config_test.go
index 410599d33..b0e1879f6 100644
--- a/internal/praefect/config/config_test.go
+++ b/internal/praefect/config/config_test.go
@@ -9,12 +9,13 @@ import (
"testing"
"time"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/log"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/prometheus"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/sentry"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
)
func TestConfigValidation(t *testing.T) {
@@ -205,14 +206,14 @@ func TestConfigValidation(t *testing.T) {
{
desc: "repositories_cleanup minimal duration is too low",
changeConfig: func(cfg *Config) {
- cfg.RepositoriesCleanup.CheckInterval = minimalSyncCheckInterval - time.Nanosecond
+ cfg.RepositoriesCleanup.CheckInterval = duration.Duration(minimalSyncCheckInterval - time.Nanosecond)
},
errMsg: `repositories_cleanup.check_interval is less then 1m0s, which could lead to a database performance problem`,
},
{
desc: "repositories_cleanup minimal duration is too low",
changeConfig: func(cfg *Config) {
- cfg.RepositoriesCleanup.RunInterval = minimalSyncRunInterval - time.Nanosecond
+ cfg.RepositoriesCleanup.RunInterval = duration.Duration(minimalSyncRunInterval - time.Nanosecond)
},
errMsg: `repositories_cleanup.run_interval is less then 1m0s, which could lead to a database performance problem`,
},
@@ -290,7 +291,7 @@ func TestConfigParsing(t *testing.T) {
},
},
Prometheus: prometheus.Config{
- ScrapeTimeout: time.Second,
+ ScrapeTimeout: duration.Duration(time.Second),
GRPCLatencyBuckets: []float64{0.1, 0.2, 0.3},
},
PrometheusExcludeDatabaseFromDefaultMetrics: true,
@@ -317,28 +318,28 @@ func TestConfigParsing(t *testing.T) {
},
},
MemoryQueueEnabled: true,
- GracefulStopTimeout: 30 * time.Second,
+ GracefulStopTimeout: duration.Duration(30 * time.Second),
Reconciliation: Reconciliation{
- SchedulingInterval: time.Minute,
+ SchedulingInterval: duration.Duration(time.Minute),
HistogramBuckets: []float64{1, 2, 3, 4, 5},
},
Replication: Replication{BatchSize: 1, ParallelStorageProcessingWorkers: 2},
Failover: Failover{
Enabled: true,
ElectionStrategy: ElectionStrategyPerRepository,
- ErrorThresholdWindow: 20 * time.Second,
+ ErrorThresholdWindow: duration.Duration(20 * time.Second),
WriteErrorThresholdCount: 1500,
ReadErrorThresholdCount: 100,
- BootstrapInterval: 1 * time.Second,
- MonitorInterval: 3 * time.Second,
+ BootstrapInterval: duration.Duration(1 * time.Second),
+ MonitorInterval: duration.Duration(3 * time.Second),
},
RepositoriesCleanup: RepositoriesCleanup{
- CheckInterval: time.Second,
- RunInterval: 3 * time.Second,
+ CheckInterval: duration.Duration(time.Second),
+ RunInterval: duration.Duration(3 * time.Second),
RepositoriesInBatch: 10,
},
BackgroundVerification: BackgroundVerification{
- VerificationInterval: 24 * time.Hour,
+ VerificationInterval: duration.Duration(24 * time.Hour),
DeleteInvalidRecords: true,
},
},
@@ -347,7 +348,7 @@ func TestConfigParsing(t *testing.T) {
desc: "overwriting default values in the config",
filePath: "testdata/config.overwritedefaults.toml",
expected: Config{
- GracefulStopTimeout: time.Minute,
+ GracefulStopTimeout: duration.Duration(time.Minute),
Reconciliation: Reconciliation{
SchedulingInterval: 0,
HistogramBuckets: []float64{1, 2, 3, 4, 5},
@@ -358,12 +359,12 @@ func TestConfigParsing(t *testing.T) {
Failover: Failover{
Enabled: false,
ElectionStrategy: "local",
- BootstrapInterval: 5 * time.Second,
- MonitorInterval: 10 * time.Second,
+ BootstrapInterval: duration.Duration(5 * time.Second),
+ MonitorInterval: duration.Duration(10 * time.Second),
},
RepositoriesCleanup: RepositoriesCleanup{
- CheckInterval: time.Second,
- RunInterval: 4 * time.Second,
+ CheckInterval: duration.Duration(time.Second),
+ RunInterval: duration.Duration(4 * time.Second),
RepositoriesInBatch: 11,
},
BackgroundVerification: DefaultBackgroundVerificationConfig(),
@@ -373,7 +374,7 @@ func TestConfigParsing(t *testing.T) {
desc: "empty config yields default values",
filePath: "testdata/config.empty.toml",
expected: Config{
- GracefulStopTimeout: time.Minute,
+ GracefulStopTimeout: duration.Duration(time.Minute),
Prometheus: prometheus.DefaultConfig(),
PrometheusExcludeDatabaseFromDefaultMetrics: true,
Reconciliation: DefaultReconciliationConfig(),
@@ -381,12 +382,12 @@ func TestConfigParsing(t *testing.T) {
Failover: Failover{
Enabled: true,
ElectionStrategy: ElectionStrategyPerRepository,
- BootstrapInterval: time.Second,
- MonitorInterval: 3 * time.Second,
+ BootstrapInterval: duration.Duration(time.Second),
+ MonitorInterval: duration.Duration(3 * time.Second),
},
RepositoriesCleanup: RepositoriesCleanup{
- CheckInterval: 30 * time.Minute,
- RunInterval: 24 * time.Hour,
+ CheckInterval: duration.Duration(30 * time.Minute),
+ RunInterval: duration.Duration(24 * time.Hour),
RepositoriesInBatch: 16,
},
BackgroundVerification: DefaultBackgroundVerificationConfig(),
@@ -521,6 +522,6 @@ func TestSerialization(t *testing.T) {
t.Run("partially set", func(t *testing.T) {
out.Reset()
require.NoError(t, encoder.Encode(Config{ListenAddr: "localhost:5640"}))
- require.Equal(t, "listen_addr = \"localhost:5640\"\n", out.String())
+ require.Equal(t, "listen_addr = 'localhost:5640'\n", out.String())
})
}
diff --git a/internal/praefect/nodes/tracker/errors.go b/internal/praefect/nodes/tracker/errors.go
index 1fce839bf..8a87d30cc 100644
--- a/internal/praefect/nodes/tracker/errors.go
+++ b/internal/praefect/nodes/tracker/errors.go
@@ -32,7 +32,7 @@ func NewErrorWindowFunction(cfg config.Failover) (ErrorWindowFunction, error) {
return nil, errors.New("errorWindow must be non zero")
}
- errorWindow := cfg.ErrorThresholdWindow
+ errorWindow := cfg.ErrorThresholdWindow.Duration()
return func(now time.Time, errorTime time.Time) bool {
return errorTime.After(now.Add(-errorWindow))
}, nil
diff --git a/internal/streamcache/cache.go b/internal/streamcache/cache.go
index 53c3c6c44..333be63c7 100644
--- a/internal/streamcache/cache.go
+++ b/internal/streamcache/cache.go
@@ -145,10 +145,10 @@ func New(cfg config.StreamCacheConfig, logger logrus.FieldLogger) Cache {
if cfg.Enabled {
packObjectsCacheEnabled.WithLabelValues(
cfg.Dir,
- strconv.Itoa(int(cfg.MaxAge.Seconds())),
+ strconv.Itoa(int(cfg.MaxAge.Duration().Seconds())),
).Set(1)
- return newCacheWithSleep(cfg.Dir, cfg.MaxAge, time.After, time.After, logger)
+ return newCacheWithSleep(cfg.Dir, cfg.MaxAge.Duration(), time.After, time.After, logger)
}
return NullCache{}
diff --git a/internal/streamcache/cache_test.go b/internal/streamcache/cache_test.go
index 01c71f6a6..4010f95fe 100644
--- a/internal/streamcache/cache_test.go
+++ b/internal/streamcache/cache_test.go
@@ -18,6 +18,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/duration"
"gitlab.com/gitlab-org/gitaly/v15/internal/log"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
)
@@ -26,7 +27,7 @@ func newCache(dir string) Cache {
return New(config.StreamCacheConfig{
Enabled: true,
Dir: dir,
- MaxAge: time.Hour,
+ MaxAge: duration.Duration(time.Hour),
}, log.Default())
}
diff --git a/internal/testhelper/testserver/praefect.go b/internal/testhelper/testserver/praefect.go
index ec930ffd8..8f4fc5040 100644
--- a/internal/testhelper/testserver/praefect.go
+++ b/internal/testhelper/testserver/praefect.go
@@ -11,7 +11,7 @@ import (
"testing"
"time"
- "github.com/pelletier/go-toml"
+ "github.com/pelletier/go-toml/v2"
"github.com/stretchr/testify/require"
gitalycfg "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v15/internal/praefect/config"