Skip to content

Commit 3a62e64

Browse files
committed
feat: add WatchChan method
This method creates a watcher for a key or prefix and unmarshals events into channel.
1 parent f9212b2 commit 3a62e64

19 files changed

Lines changed: 1096 additions & 446 deletions

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ on:
1414
schedule:
1515
- cron: '0 5 * * 4'
1616

17+
concurrency:
18+
group: '${{ github.head_ref || github.ref }}'
19+
cancel-in-progress: true
20+
1721
jobs:
1822
analyze:
1923
name: Analyze

.github/workflows/push.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
name: build
22
on: [push, pull_request]
33

4+
concurrency:
5+
group: '${{ github.head_ref || github.ref }}'
6+
cancel-in-progress: true
7+
48
jobs:
59
lint:
610
runs-on: ubuntu-latest

.golangci.yml

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
# options for analysis running
1+
---
22
run:
3-
tests: true
4-
timeout: 3m
5-
6-
7-
# all available settings of specific linters
3+
tests: false
4+
skip-dirs:
5+
- .github
6+
- build
7+
- web
8+
- .go
89
linters-settings:
910
dupl:
10-
threshold: 150
11+
threshold: 100
1112
funlen:
1213
lines: 100
1314
statements: 50
1415
goconst:
1516
min-len: 2
16-
min-occurrences: 3
17+
min-occurrences: 2
1718
gocritic:
1819
enabled-tags:
1920
- diagnostic
@@ -22,22 +23,26 @@ linters-settings:
2223
- performance
2324
- style
2425
disabled-checks:
25-
- whyNoLint
26+
- hugeParam
2627
gocyclo:
27-
min-complexity: 15
28-
goimports:
29-
local-prefixes: github.com/ewohltman/ephemeral-roles
28+
min-complexity: 20
3029
revive:
3130
min-confidence: 0.8
3231
govet:
3332
check-shadowing: true
33+
lll:
34+
line-length: 140
3435
misspell:
3536
locale: US
37+
nolintlint:
38+
allow-leading-space: false
39+
allow-no-explanation:
40+
- gocognit
41+
- funlen
42+
- gocyclo
3643

3744
linters:
38-
disable:
39-
- gomnd
40-
- lll
45+
disable-all: true
4146
enable:
4247
- bodyclose
4348
- deadcode
@@ -46,13 +51,13 @@ linters:
4651
- dupl
4752
- errcheck
4853
- funlen
54+
- nolintlint
4955
- gochecknoglobals
5056
- gochecknoinits
5157
- gocognit
5258
- goconst
5359
- gocritic
5460
- gocyclo
55-
- godox
5661
- gofmt
5762
- goimports
5863
- revive
@@ -77,11 +82,11 @@ linters:
7782
- whitespace
7883
- wsl
7984

80-
8185
issues:
8286
exclude:
8387
# Very commonly not checked.
84-
- 'Error return value of .(l.Sync|.*Close|.*Flush|os\.Remove(All)?|os\.(Un)?Setenv). is not checked'
88+
- 'Error return value of .(l.Sync|.*Close|.*.Write|.*Flush|os\.Remove(All)?|os\.(Un)?Setenv). is not checked'
89+
- 'G104:.*'
8590
- 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON) should have comment or be unexported'
8691
- 'shadow: declaration of "err" shadows declaration.*'
8792
max-same-issues: 0

encoding.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

encoding_test.go

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@ import (
88
"github.com/stretchr/testify/require"
99
)
1010

11-
func TestUnmarshalList(t *testing.T) {
12-
count := 1000
13-
b := newMockBackend(count)
14-
l := []testStruct{}
15-
err := UnmarshalJSONList(&l, "", b)
16-
require.NoError(t, err)
17-
assert.Len(t, l, count)
18-
}
19-
2011
func TestUnmarshal(t *testing.T) {
2112
count := 1000
2213
b := newMockBackend(count)
@@ -34,19 +25,6 @@ func TestUnmarshal(t *testing.T) {
3425
assert.Len(t, l, count)
3526
}
3627

37-
func benchmarkUnmarshalList(i int, b *testing.B) {
38-
b.StopTimer()
39-
40-
back := newMockBackend(i)
41-
42-
b.ReportAllocs()
43-
b.StartTimer()
44-
45-
for n := 0; n < b.N; n++ {
46-
l := []testStruct{}
47-
_ = UnmarshalJSONList(&l, "", back)
48-
}
49-
}
5028
func benchmarkUnmarshal(i int, b *testing.B) {
5129
b.StopTimer()
5230

@@ -72,26 +50,16 @@ func benchmarkUnmarshal(i int, b *testing.B) {
7250

7351
/*
7452
BenchmarkUnmarshal10-4 200000 194390 ns/op
75-
BenchmarkUnmarshalList10-4 300000 201912 ns/op
7653
BenchmarkUnmarshal100-4 20000 2076871 ns/op
77-
BenchmarkUnmarshalList100-4 20000 2110142 ns/op
7854
BenchmarkUnmarshal1000-4 2000 21495289 ns/op
79-
BenchmarkUnmarshalList1000-4 2000 21822339 ns/op
8055
BenchmarkUnmarshal10000-4 200 233705937 ns/op
81-
BenchmarkUnmarshalList10000-4 200 211692563 ns/op
8256
BenchmarkUnmarshal100000-4 20 2317840686 ns/op
83-
BenchmarkUnmarshalList100000-4 20 2118017559 ns/op
8457
*/
85-
func BenchmarkUnmarshal10(b *testing.B) { benchmarkUnmarshal(10, b) }
86-
func BenchmarkUnmarshalList10(b *testing.B) { benchmarkUnmarshalList(10, b) }
87-
func BenchmarkUnmarshal100(b *testing.B) { benchmarkUnmarshal(100, b) }
88-
func BenchmarkUnmarshalList100(b *testing.B) { benchmarkUnmarshalList(100, b) }
89-
func BenchmarkUnmarshal1000(b *testing.B) { benchmarkUnmarshal(1000, b) }
90-
func BenchmarkUnmarshalList1000(b *testing.B) { benchmarkUnmarshalList(1000, b) }
91-
func BenchmarkUnmarshal10000(b *testing.B) { benchmarkUnmarshal(10000, b) }
92-
func BenchmarkUnmarshalList10000(b *testing.B) { benchmarkUnmarshalList(10000, b) }
93-
func BenchmarkUnmarshal100000(b *testing.B) { benchmarkUnmarshal(100000, b) }
94-
func BenchmarkUnmarshalList100000(b *testing.B) { benchmarkUnmarshalList(100000, b) }
58+
func BenchmarkUnmarshal10(b *testing.B) { benchmarkUnmarshal(10, b) }
59+
func BenchmarkUnmarshal100(b *testing.B) { benchmarkUnmarshal(100, b) }
60+
func BenchmarkUnmarshal1000(b *testing.B) { benchmarkUnmarshal(1000, b) }
61+
func BenchmarkUnmarshal10000(b *testing.B) { benchmarkUnmarshal(10000, b) }
62+
func BenchmarkUnmarshal100000(b *testing.B) { benchmarkUnmarshal(100000, b) }
9563

9664
type mockBackend struct {
9765
entries []Entry
@@ -136,6 +104,10 @@ func (mockBackend) Close() error {
136104
return nil
137105
}
138106

107+
func (m *mockBackend) WatchChan(string, interface{}, chan error, ...WatchOption) (WatchStarter, error) {
108+
return nil, nil
109+
}
110+
139111
func newMockBackend(max int) Backend {
140112
entries := make([]Entry, 0, max)
141113
for i := 0; i < max; i++ {
@@ -188,5 +160,4 @@ type testStruct struct {
188160
} `json:"commands"`
189161
}
190162

191-
//nolint:gochecknoglobals
192-
var data = `{"id":"admin:lslb-pool","organization":"admin","name":"lslb-pool","description":"","user":"","group":"","shell":"bash","timeout":0,"interval":300000000000,"constraints":{"os":["linux"],"host":["p1-linux-mlsu005","p1-linux-mlsu006"],"files":["/usr/bin/lslb"]},"discovery":{"script":{"data":"echo \"fake-pool\"\n# sudo /usr/bin/lslb pools","rediscover":false}},"tags":null,"commands":{"start":{"shell":"/bin/true","timeout":"10s","rediscover":false},"status":{"shell":"/bin/true","timeout":"10s","rediscover":false},"stop":{"shell":"/bin/true","timeout":"10s","rediscover":false}}}`
163+
const data = `{"id":"admin:lslb-pool","organization":"admin","name":"lslb-pool","description":"","user":"","group":"","shell":"bash","timeout":0,"interval":300000000000,"constraints":{"os":["linux"],"host":["p1-linux-mlsu005","p1-linux-mlsu006"],"files":["/usr/bin/lslb"]},"discovery":{"script":{"data":"echo \"fake-pool\"\n# sudo /usr/bin/lslb pools","rediscover":false}},"tags":null,"commands":{"start":{"shell":"/bin/true","timeout":"10s","rediscover":false},"status":{"shell":"/bin/true","timeout":"10s","rediscover":false},"stop":{"shell":"/bin/true","timeout":"10s","rediscover":false}}}`

etcd/config.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import (
1717

1818
// Constants
1919
const (
20-
DfltSeparator = '/'
21-
DfltKeepAliveTTL = 30 * time.Second
20+
DfltSeparator = '/'
21+
DfltKeepAliveTTL = 30 * time.Second
22+
DfltWatchNotifyTimeout = 5 * time.Second
2223
)
2324

2425
// verify that *Backend implements store.Backend
@@ -28,8 +29,9 @@ var _ store.Backend = &Backend{}
2829
// has to be used.
2930
func New(opts ...Opt) (*Backend, error) {
3031
e := Backend{
31-
separator: DfltSeparator,
32-
errHandler: func(err error) error { return err },
32+
separator: DfltSeparator,
33+
errHandler: func(err error) error { return err },
34+
watchNotifyTimeout: DfltWatchNotifyTimeout,
3335
}
3436

3537
for _, option := range opts {
@@ -121,6 +123,20 @@ func WithRequestTimeout(timeout time.Duration) Opt {
121123
}
122124
}
123125

126+
// WithWatchNotifyTimeout determines how long to wait for a
127+
// watch notify create event. Default is 5s.
128+
func WithWatchNotifyTimeout(timeout time.Duration) Opt {
129+
return func(e *Backend) error {
130+
if timeout <= 0 {
131+
return errors.New("watch notify timeout cannot be <= 0")
132+
}
133+
134+
e.watchNotifyTimeout = timeout
135+
136+
return nil
137+
}
138+
}
139+
124140
// WithUsername is an option to configure etcd username.
125141
func WithUsername(username string) Opt {
126142
return func(e *Backend) error {

etcd/etcdv3.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type Backend struct {
3333
ctx context.Context
3434
errHandler store.ErrorFunc
3535
dialOptions []grpc.DialOption
36+
watchNotifyTimeout time.Duration
3637
}
3738

3839
// AbsKey will convert a relativ key in a absolute key
@@ -82,7 +83,6 @@ func (e *Backend) KeyLeaf(key string) string {
8283
}
8384

8485
// Put is used to insert or update an entry
85-
//nolint:gocyclo
8686
func (e *Backend) Put(entry *store.Entry, ops ...store.PutOption) (bool, error) {
8787
opts := &store.PutOptions{}
8888

@@ -145,7 +145,6 @@ func (e *Backend) Put(entry *store.Entry, ops ...store.PutOption) (bool, error)
145145
}
146146

147147
// Get is used to fetch an one ore many entries.
148-
//nolint:gocyclo
149148
func (e *Backend) Get(key string, ops ...store.GetOption) ([]store.Entry, error) {
150149
opts := &store.GetOptions{}
151150

etcd/etcdv3_test.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -465,40 +465,6 @@ func TestMarshal(t *testing.T) {
465465
}
466466
}
467467

468-
func TestMarshal2(t *testing.T) {
469-
integration.BeforeTestExternal(t)
470-
471-
for _, p := range []string{"", "root"} {
472-
opts := []Opt{}
473-
if p != "" {
474-
opts = append(opts, WithPrefix(p))
475-
}
476-
477-
b, _, teardown := setupTestStore(t, false, opts)
478-
479-
type testStruct struct {
480-
Value1 string
481-
Value2 int
482-
}
483-
484-
exp := testStruct{
485-
Value1: "value1",
486-
Value2: 42,
487-
}
488-
key := "key"
489-
value, err := json.Marshal(exp)
490-
require.NoError(t, err)
491-
_, err = b.Put(&store.Entry{Key: key, Value: value})
492-
require.NoError(t, err)
493-
494-
bla := []testStruct{}
495-
err = store.UnmarshalJSONList(&bla, key, b)
496-
require.NoError(t, err)
497-
498-
teardown()
499-
}
500-
}
501-
502468
/*
503469
SetupTestStore starts an embedded etcd server.
504470
The returned function shall be used as teardown function.

0 commit comments

Comments
 (0)