forked from sensu/sensu-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
67 lines (54 loc) · 1.89 KB
/
proxy.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
package store
import (
"context"
"sync/atomic"
"unsafe"
corev2 "github.com/sensu/sensu-go/api/core/v2"
"github.com/sensu/sensu-go/types"
)
// EventStoreProxy is a mechanism for providing an EventStore with a replaceable
// underlying implementation. It uses an atomic so that calls are not impeded by
// mutex overhead.
type EventStoreProxy struct {
impl unsafe.Pointer
// guard against the store being garbage collected,
// which would cause a crash if there were no more references
// to it and the impl was dereferenced.
gcGuard EventStore
}
func NewEventStoreProxy(s EventStore) *EventStoreProxy {
return &EventStoreProxy{
impl: unsafe.Pointer(&s),
gcGuard: s,
}
}
func (e *EventStoreProxy) do() EventStore {
return *((*EventStore)(atomic.LoadPointer(&e.impl)))
}
func (e *EventStoreProxy) DeleteEventByEntityCheck(ctx context.Context, entity, check string) error {
return e.do().DeleteEventByEntityCheck(ctx, entity, check)
}
func (e *EventStoreProxy) GetEvents(ctx context.Context, pred *SelectionPredicate) ([]*corev2.Event, error) {
return e.do().GetEvents(ctx, pred)
}
func (e *EventStoreProxy) GetEventsByEntity(ctx context.Context, entity string, pred *SelectionPredicate) ([]*corev2.Event, error) {
return e.do().GetEventsByEntity(ctx, entity, pred)
}
func (e *EventStoreProxy) GetEventByEntityCheck(ctx context.Context, entity, check string) (*types.Event, error) {
return e.do().GetEventByEntityCheck(ctx, entity, check)
}
func (e *EventStoreProxy) UpdateEvent(ctx context.Context, event *types.Event) (old, new *types.Event, err error) {
return e.do().UpdateEvent(ctx, event)
}
type closer interface {
Close() error
}
func (e *EventStoreProxy) UpdateEventStore(to EventStore) {
oldptr := atomic.SwapPointer(&e.impl, unsafe.Pointer(&to))
old := *((*EventStore)(oldptr))
if s, ok := old.(closer); ok {
// Attempt to close the old store
defer s.Close()
}
e.gcGuard = to
}