github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/persistence/plugin.go (about) 1 package persistence 2 3 import ( 4 "github.com/asynkron/protoactor-go/actor" 5 "google.golang.org/protobuf/proto" 6 ) 7 8 type persistent interface { 9 init(provider Provider, context actor.Context) 10 PersistReceive(message proto.Message) 11 PersistSnapshot(snapshot proto.Message) 12 Recovering() bool 13 Name() string 14 } 15 16 type Mixin struct { 17 eventIndex int 18 providerState ProviderState 19 name string 20 receiver receiver 21 recovering bool 22 } 23 24 // enforces that Mixin implements persistent interface 25 // (if they diverge, code breaks in other packages) 26 var _ persistent = (*Mixin)(nil) 27 28 func (mixin *Mixin) Recovering() bool { 29 return mixin.recovering 30 } 31 32 func (mixin *Mixin) Name() string { 33 return mixin.name 34 } 35 36 func (mixin *Mixin) PersistReceive(message proto.Message) { 37 mixin.providerState.PersistEvent(mixin.Name(), mixin.eventIndex, message) 38 if mixin.eventIndex%mixin.providerState.GetSnapshotInterval() == 0 { 39 mixin.receiver.Receive(&actor.MessageEnvelope{Message: &RequestSnapshot{}}) 40 } 41 mixin.eventIndex++ 42 } 43 44 func (mixin *Mixin) PersistSnapshot(snapshot proto.Message) { 45 mixin.providerState.PersistSnapshot(mixin.Name(), mixin.eventIndex, snapshot) 46 } 47 48 func (mixin *Mixin) init(provider Provider, context actor.Context) { 49 if mixin.providerState == nil { 50 mixin.providerState = provider.GetState() 51 } 52 53 receiver := context.(receiver) 54 55 mixin.name = context.Self().Id 56 mixin.eventIndex = 0 57 mixin.receiver = receiver 58 mixin.recovering = true 59 60 mixin.providerState.Restart() 61 if snapshot, eventIndex, ok := mixin.providerState.GetSnapshot(mixin.Name()); ok { 62 mixin.eventIndex = eventIndex 63 receiver.Receive(&actor.MessageEnvelope{Message: snapshot}) 64 } 65 mixin.providerState.GetEvents(mixin.Name(), mixin.eventIndex, 0 /* 0 means max */, func(e interface{}) { 66 receiver.Receive(&actor.MessageEnvelope{Message: e}) 67 mixin.eventIndex++ 68 }) 69 mixin.recovering = false 70 receiver.Receive(&actor.MessageEnvelope{Message: &ReplayComplete{}}) 71 } 72 73 type receiver interface { 74 Receive(message *actor.MessageEnvelope) 75 }