Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.

Commit 1028e38

Browse files
committed
Fixes around worker locker
- test coverage - worker by default not required locker (settings) - there's interface to apply settings for custom locker (redis, etc) Signed-off-by: Evgeniy Kulikov <[email protected]>
1 parent f8a4933 commit 1028e38

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed

workers/errors.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const (
1313
// ErrEmptyWorkers when workers not passed to params
1414
ErrEmptyWorkers = Error("empty workers")
1515

16+
// ErrEmptyLocker when locker required,
17+
// but not passed to params
18+
ErrEmptyLocker = Error("empty locker")
19+
1620
// ErrEmptyJob when worker job is nil
1721
ErrEmptyJob = Error("empty job")
1822
)

workers/workers.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ type (
2020
Locker worker.Locker `optional:"true"`
2121
}
2222

23+
// LockerSettings creates copy of locker and applies settings
24+
LockerSettings interface {
25+
Apply(key string, v *viper.Viper) (worker.Locker, error)
26+
}
27+
2328
options struct {
2429
Name string
2530
Job worker.Job
@@ -103,8 +108,20 @@ func workerByConfig(opts options) (*worker.Worker, error) {
103108
if opts.Viper.IsSet(key + ".immediately") {
104109
w = w.SetImmediately(opts.Viper.GetBool(key + ".immediately"))
105110
}
106-
if opts.Locker != nil {
107-
w = w.WithLock(opts.Locker)
111+
112+
if opts.Viper.IsSet(key + ".lock") {
113+
if opts.Locker == nil {
114+
return nil, errors.Wrap(ErrEmptyLocker, key)
115+
} else if l, ok := opts.Locker.(LockerSettings); ok {
116+
locker, err := l.Apply(key, opts.Viper)
117+
if err != nil {
118+
return nil, err
119+
}
120+
121+
w = w.WithLock(locker)
122+
} else {
123+
w = w.WithLock(opts.Locker)
124+
}
108125
}
109126

110127
return w, nil

workers/workers_test.go

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ import (
1414
"github.com/stretchr/testify/require"
1515
)
1616

17-
type config = map[string]interface{}
17+
type (
18+
config = map[string]interface{}
19+
20+
testLocker struct{ locked int32 }
21+
customLocker struct{ testLocker }
22+
)
23+
24+
const errFailToApplyLockerSettings = Error("fail to apply locker settings")
1825

1926
func mockedViper(cfg config) *viper.Viper {
2027
v := viper.New()
@@ -28,18 +35,21 @@ func mockedViper(cfg config) *viper.Viper {
2835
return v
2936
}
3037

31-
type customLocker struct {
32-
locked int32
38+
func (c *customLocker) Apply(key string, v *viper.Viper) (worker.Locker, error) {
39+
if v.GetBool(key + ".lock.fail") {
40+
return c, errFailToApplyLockerSettings
41+
}
42+
return c, nil
3343
}
3444

35-
func (c *customLocker) Lock() error {
45+
func (c *testLocker) Lock() error {
3646
if atomic.CompareAndSwapInt32(&c.locked, 0, 1) {
3747
return nil
3848
}
3949
return errors.New("locked")
4050
}
4151

42-
func (c *customLocker) Unlock() {
52+
func (c *testLocker) Unlock() {
4353
atomic.StoreInt32(&c.locked, 0)
4454
}
4555

@@ -135,7 +145,26 @@ func Test_workerByConfig(t *testing.T) {
135145
Viper: mockedViper(config{}),
136146
}},
137147

138-
{name: "good case",
148+
{
149+
name: "missing locker",
150+
err: ErrEmptyLocker,
151+
args: options{
152+
Name: "test",
153+
Job: nopJob,
154+
Viper: mockedViper(config{
155+
"disabled": false,
156+
"timer": time.Millisecond,
157+
"ticker": time.Millisecond,
158+
"cron": "0 1 * * * *",
159+
"immediately": true,
160+
"lock": true,
161+
}),
162+
},
163+
},
164+
165+
{
166+
name: "error when apply locker settings",
167+
err: errFailToApplyLockerSettings,
139168
args: options{
140169
Name: "test",
141170
Job: nopJob,
@@ -146,6 +175,57 @@ func Test_workerByConfig(t *testing.T) {
146175
"ticker": time.Millisecond,
147176
"cron": "0 1 * * * *",
148177
"immediately": true,
178+
"lock": true,
179+
"lock.fail": true,
180+
}),
181+
},
182+
},
183+
184+
{
185+
name: "good case",
186+
args: options{
187+
Name: "test",
188+
Job: nopJob,
189+
Viper: mockedViper(config{
190+
"disabled": false,
191+
"timer": time.Millisecond,
192+
"ticker": time.Millisecond,
193+
"cron": "0 1 * * * *",
194+
"immediately": true,
195+
}),
196+
},
197+
},
198+
199+
{
200+
name: "good case with custom locker",
201+
args: options{
202+
Name: "test",
203+
Job: nopJob,
204+
Locker: &customLocker{},
205+
Viper: mockedViper(config{
206+
"disabled": false,
207+
"timer": time.Millisecond,
208+
"ticker": time.Millisecond,
209+
"cron": "0 1 * * * *",
210+
"immediately": true,
211+
"lock": true,
212+
}),
213+
},
214+
},
215+
216+
{
217+
name: "good case with simple locker",
218+
args: options{
219+
Name: "test",
220+
Job: nopJob,
221+
Locker: &testLocker{},
222+
Viper: mockedViper(config{
223+
"disabled": false,
224+
"timer": time.Millisecond,
225+
"ticker": time.Millisecond,
226+
"cron": "0 1 * * * *",
227+
"immediately": true,
228+
"lock": true,
149229
}),
150230
},
151231
},

0 commit comments

Comments
 (0)