-
Notifications
You must be signed in to change notification settings - Fork 0
/
run_at_least.go
64 lines (51 loc) · 1.47 KB
/
run_at_least.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
package ctxroutines
import (
"context"
"time"
)
type bypass func(error) bool
func onlySuccess(err error) (skip bool) { return err != nil }
func onlyFail(err error) (skip bool) { return err == nil }
func noBypass(err error) (skip bool) { return }
type runAtLeast struct {
dur time.Duration
Runner
bypass
}
func (r *runAtLeast) Run() (err error) {
ctx, cancel := context.WithTimeout(context.Background(), r.dur)
defer cancel()
err = r.Runner.Run()
if !r.bypass(err) {
<-ctx.Done()
}
return
}
func newRAL(dur time.Duration, f Runner, b bypass) (ret *runAtLeast) {
ret = &runAtLeast{
dur: dur,
Runner: f,
bypass: b,
}
return
}
// RunAtLeast ensures the execution time of f is longer than dur
//
// Say you have an empty Runner f
//
// r := RunAtLeast(time.Second, f)
// r.Run() // runs f immediately, blocks 1s
func RunAtLeast(dur time.Duration, f Runner) (ret Runner) {
return newRAL(dur, f, noBypass)
}
// RunAtLeastSuccess is like RunAtLeast, but only successful call counts
func RunAtLeastSuccess(dur time.Duration, f Runner) (ret Runner) {
return newRAL(dur, f, onlySuccess)
}
// RunAtLeastFailed is like RunAtLeast, but only failed call counts
func RunAtLeastFailed(dur time.Duration, f Runner) (ret Runner) {
return newRAL(dur, f, onlyFail)
}