carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "os"
6 "sync/atomic"
7 "time"
8
9 "github.com/carlosframework/platform/internal/rootstate"
10)
11
12type ReleaseExclusion struct {
13 Open func() (rootstate.Store, error)
14 Wait time.Duration
15}
16
17type releaseHeldKey struct{}
18type releaseHeld struct {
19 owner *ReleaseExclusion
20 active atomic.Bool
21}
22
23func (x *ReleaseExclusion) Check(ctx context.Context) error {
24 held, _ := ctx.Value(releaseHeldKey{}).(*releaseHeld)
25 if x == nil || held == nil || held.owner != x || !held.active.Load() {
26 return os.ErrPermission
27 }
28 return ctx.Err()
29}
30
31func (x *ReleaseExclusion) With(ctx context.Context, fn func(context.Context) error) error {
32 if x == nil || x.Open == nil || fn == nil {
33 return os.ErrPermission
34 }
35 if ctx.Value(releaseHeldKey{}) != nil {
36 if err := x.Check(ctx); err != nil {
37 return err
38 }
39 return fn(ctx)
40 }
41 store, err := x.Open()
42 if err != nil {
43 return err
44 }
45 if store == nil {
46 return os.ErrPermission
47 }
48 defer store.Close()
49 wait := ctx
50 cancel := func() {}
51 if x.Wait > 0 {
52 wait, cancel = context.WithTimeout(ctx, x.Wait)
53 }
54 defer cancel()
55 return rootstate.WithRelease(wait, store, func() error {
56 cancel()
57 held := &releaseHeld{owner: x}
58 held.active.Store(true)
59 defer held.active.Store(false)
60 return fn(context.WithValue(ctx, releaseHeldKey{}, held))
61 })
62}
63