generated from dogmatiq/template-go
-
Notifications
You must be signed in to change notification settings - Fork 2
/
sleep.go
92 lines (84 loc) · 2.91 KB
/
sleep.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package linger
import (
"context"
"time"
)
// Sleep pauses the current goroutine until some duration has elapsed.
//
// The sleep duration computed by finding the first of the supplied durations
// that is positive. It returns immediately if none of the supplied durations
// are positive.
//
// It sleeps until the duration elapses or ctx is canceled, whichever is first.
// If ctx is canceled before the duration elapses it returns ctx.Err(),
// otherwise it returns nil.
func Sleep(ctx context.Context, durations ...time.Duration) error {
return SleepX(ctx, Identity, durations...)
}
// SleepX pauses the current goroutine until some duration has elapsed.
//
// The sleep duration computed by finding the first of the supplied durations
// that is positive, then applying the transform x. It returns immediately if
// none of the supplied durations are positive.
//
// The transform can be used to apply jitter to the sleep duration, for example,
// by using one of the built-in jitter transforms such as FullJitter() or
// ProportionalJitter().
//
// It sleeps until the duration elapses or ctx is canceled, whichever is first.
// If ctx is canceled before the duration elapses it returns ctx.Err(),
// otherwise it returns nil.
func SleepX(
ctx context.Context,
x DurationTransform,
durations ...time.Duration,
) error {
d, _ := Coalesce(durations...)
return sleep(ctx, x, d)
}
// SleepUntil pauses the current goroutine until a specific time.
//
// The sleep duration is computed by finding the amount of time until the
// earliest of the supplied times. It returns immediately if the earliest of the
// times is in the past.
//
// It sleeps until the time is reached or ctx is canceled, whichever is first.
// If ctx is canceled before the time is reached it returns ctx.Err(),
// otherwise it returns nil.
func SleepUntil(ctx context.Context, times ...time.Time) error {
return SleepUntilX(ctx, Identity, times...)
}
// SleepUntilX pauses the current goroutine until a specific time.
//
// The sleep duration is computed by finding the amount of time until the
// earliest of the supplied times, then applying the transform x. It returns
// immediately if the earliest of the times is in the past.
//
// The transform can be used to apply jitter to the sleep duration, for example,
// by using one of the built-in jitter transforms such as FullJitter() or
// ProportionalJitter().
//
// It sleeps until the time is reached or ctx is canceled, whichever is first.
// If ctx is canceled before the time is reached it returns ctx.Err(),
// otherwise it returns nil.
func SleepUntilX(
ctx context.Context,
x DurationTransform,
times ...time.Time,
) error {
d := time.Until(Earliest(times...))
return sleep(ctx, x, d)
}
func sleep(ctx context.Context, x DurationTransform, d time.Duration) error {
if d <= 0 {
return ctx.Err()
}
t := time.NewTimer(x(d))
defer t.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-t.C:
return nil
}
}