Skip to content

Commit a1939d1

Browse files
authored
chore: add config validations (#111)
1 parent 9ae52b9 commit a1939d1

File tree

4 files changed

+121
-3
lines changed

4 files changed

+121
-3
lines changed

cmd/seq-db/seq-db.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ func main() {
7777
logger.Fatal("cannot parse config file", zap.Error(err))
7878
}
7979

80+
if err := cfg.Validate(*flagMode); err != nil {
81+
logger.Fatal("config validation failed", zap.Error(err))
82+
}
83+
8084
config.ReaderWorkers = cfg.Resources.ReaderWorkers
8185
config.CaseSensitive = cfg.Indexing.CaseSensitive
8286
config.SkipFsync = cfg.Resources.SkipFsync

config/validation.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package config
2+
3+
import (
4+
"cmp"
5+
"fmt"
6+
)
7+
8+
type validateFn func() error
9+
10+
func (c *Config) Validate(mode string) error {
11+
validations := []validateFn{
12+
notEmpty("mapping.path", c.Mapping.Path),
13+
inRange("tracing.sampling_rate", 0, 1, c.Tracing.SamplingRate),
14+
}
15+
16+
switch mode {
17+
case "store":
18+
validations = append(validations, c.storeValidations()...)
19+
case "proxy":
20+
validations = append(validations, c.proxyValidations()...)
21+
case "single":
22+
validations = append(validations, c.proxyValidations()...)
23+
validations = append(validations, c.storeValidations()...)
24+
default:
25+
panic("unknown mode")
26+
}
27+
28+
for _, fn := range validations {
29+
if err := fn(); err != nil {
30+
return err
31+
}
32+
}
33+
34+
return nil
35+
}
36+
37+
func (c *Config) proxyValidations() []validateFn {
38+
return []validateFn{
39+
inRange("compression.docs_zstd_compression_level", -7, 22, c.Compression.DocsZstdCompressionLevel),
40+
inRange("compression.metas_zstd_compression_level", -7, 22, c.Compression.MetasZstdCompressionLevel),
41+
42+
greaterThan("limits.query_rate", 0, c.Limits.QueryRate),
43+
greaterThan("limits.inflight_bulks", 0, c.Limits.InflightBulks),
44+
greaterThan("limits.doc_size", 0, c.Limits.DocSize),
45+
}
46+
}
47+
48+
func (c *Config) storeValidations() []validateFn {
49+
validations := []validateFn{
50+
notEmpty("storage.data_dir", c.Storage.DataDir),
51+
greaterThan("storage.frac_size", 0, c.Storage.FracSize),
52+
greaterThan("storage.total_size", 0, c.Storage.TotalSize),
53+
54+
greaterThan("limits.search_requests", 0, c.Limits.SearchRequests),
55+
greaterThan("limits.bulk_requests", 0, c.Limits.BulkRequests),
56+
greaterThan("limits.fraction_hits", 0, c.Limits.FractionHits),
57+
greaterThan("limits.search_docs", 0, c.Limits.SearchDocs),
58+
59+
greaterThan("limits.aggregation.field_tokens", 0, c.Limits.Aggregation.FieldTokens),
60+
greaterThan("limits.aggregation.group_tokens", 0, c.Limits.Aggregation.GroupTokens),
61+
greaterThan("limits.aggregation.fraction_tokens", 0, c.Limits.Aggregation.FractionTokens),
62+
63+
greaterThan("resources.reader_workers", 0, c.Resources.ReaderWorkers),
64+
greaterThan("resources.search_workers", 0, c.Resources.SearchWorkers),
65+
greaterThan("resources.cache_size", 0, c.Resources.CacheSize),
66+
67+
inRange("compression.sealed_zstd_compression_level", -7, 22, c.Compression.SealedZstdCompressionLevel),
68+
inRange("compression.doc_block_zstd_compression_level", -7, 22, c.Compression.DocBlockZstdCompressionLevel),
69+
}
70+
71+
if c.Offloading.Enabled {
72+
validations = append(validations,
73+
notEmpty("offloading.bucket", c.Offloading.Bucket),
74+
notEmpty("offloading.access_key", c.Offloading.AccessKey),
75+
notEmpty("offloading.secret_key", c.Offloading.SecretKey),
76+
)
77+
}
78+
79+
return validations
80+
}
81+
82+
func notEmpty[T comparable](field string, v T) validateFn {
83+
return func() error {
84+
var z T
85+
if v == z {
86+
return fmt.Errorf("field %q is required", field)
87+
}
88+
return nil
89+
}
90+
}
91+
92+
func greaterThan[T cmp.Ordered](field string, base, v T) validateFn {
93+
return func() error {
94+
if v <= base {
95+
return fmt.Errorf(
96+
"field %q must be greater than %v",
97+
field, base,
98+
)
99+
}
100+
return nil
101+
}
102+
}
103+
104+
func inRange[T cmp.Ordered](field string, from, to, v T) validateFn {
105+
return func() error {
106+
if v < from || to < v {
107+
return fmt.Errorf(
108+
"field %q must be in range [%v; %v]",
109+
field, from, to,
110+
)
111+
}
112+
return nil
113+
}
114+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ require (
3333
go.uber.org/multierr v1.11.0
3434
go.uber.org/zap v1.27.0
3535
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
36-
golang.org/x/sync v0.15.0
36+
golang.org/x/sync v0.16.0
3737
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
3838
google.golang.org/grpc v1.74.2
3939
google.golang.org/protobuf v1.36.6

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
349349
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
350350
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
351351
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
352-
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
353-
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
352+
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
353+
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
354354
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
355355
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
356356
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

0 commit comments

Comments
 (0)