oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1package calendar
2
3import (
4 "context"
5 "time"
6)
7
8// The drain's budgets: what a send may use of one, and what is kept
9// back for recording its outcome.
10
11// keepReserve is the part of every budget that belongs to bookkeeping,
12// not sending: sends stop this long before the deadline, and the
13// outcome of the last one is recorded inside it.
14const keepReserve = 2 * time.Second
15
16// sendBudget is what a send may use of ctx: everything but the
17// reserve. A context with no deadline is left alone.
18func sendBudget(ctx context.Context) (context.Context, context.CancelFunc) {
19 if dl, ok := ctx.Deadline(); ok {
20 return context.WithDeadline(ctx, dl.Add(-keepReserve))
21 }
22 return context.WithCancel(ctx)
23}
24
25// keep is the bookkeeping context: what a send's outcome is recorded
26// under. Detached from cancellation — a send that ran out its budget
27// still has to be marked failed or deferred, or the lease does the
28// same job five minutes later at the cost of a duplicate — and bounded
29// by what is left of ctx's own deadline, floored at keepFloor so a
30// late claim still gets its outcome recorded. That floor is the whole
31// of the overrun a budget can suffer.
32func keep(ctx context.Context) context.Context {
33 left := keepReserve
34 if dl, ok := ctx.Deadline(); ok {
35 if until := time.Until(dl); until < left {
36 left = until
37 }
38 }
39 if left < keepFloor {
40 left = keepFloor
41 }
42 k, cancel := context.WithTimeout(context.WithoutCancel(ctx), left)
43 _ = cancel // released by the timeout; the store calls are short
44 return k
45}
46
47// keepFloor is the least a bookkeeping call is given, whatever the
48// clock says.
49const keepFloor = time.Second
50