github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/persistence/in_memory_provider.go (about) 1 package persistence 2 3 import ( 4 "sync" 5 6 "google.golang.org/protobuf/proto" 7 ) 8 9 type entry struct { 10 eventIndex int // the event index right after snapshot 11 snapshot proto.Message 12 events []proto.Message 13 } 14 15 type InMemoryProvider struct { 16 snapshotInterval int 17 mu sync.RWMutex 18 store map[string]*entry // actorName -> a persistence entry 19 } 20 21 func NewInMemoryProvider(snapshotInterval int) *InMemoryProvider { 22 return &InMemoryProvider{ 23 snapshotInterval: snapshotInterval, 24 store: make(map[string]*entry), 25 } 26 } 27 28 // loadOrInit returns the existing entry for actorName if present. 29 // Otherwise, it initializes and returns an empty entry. 30 // The loaded result is true if the entry was loaded, false if initialized. 31 func (provider *InMemoryProvider) loadOrInit(actorName string) (e *entry, loaded bool) { 32 provider.mu.RLock() 33 e, ok := provider.store[actorName] 34 provider.mu.RUnlock() 35 36 if !ok { 37 provider.mu.Lock() 38 e = &entry{} 39 provider.store[actorName] = e 40 provider.mu.Unlock() 41 } 42 43 return e, ok 44 } 45 46 func (provider *InMemoryProvider) Restart() {} 47 48 func (provider *InMemoryProvider) GetSnapshotInterval() int { 49 return provider.snapshotInterval 50 } 51 52 func (provider *InMemoryProvider) GetSnapshot(actorName string) (snapshot interface{}, eventIndex int, ok bool) { 53 entry, loaded := provider.loadOrInit(actorName) 54 if !loaded || entry.snapshot == nil { 55 return nil, 0, false 56 } 57 return entry.snapshot, entry.eventIndex, true 58 } 59 60 func (provider *InMemoryProvider) PersistSnapshot(actorName string, eventIndex int, snapshot proto.Message) { 61 entry, _ := provider.loadOrInit(actorName) 62 entry.eventIndex = eventIndex 63 entry.snapshot = snapshot 64 } 65 66 func (provider *InMemoryProvider) DeleteSnapshots(actorName string, inclusiveToIndex int) { 67 } 68 69 func (provider *InMemoryProvider) GetEvents(actorName string, eventIndexStart int, eventIndexEnd int, callback func(e interface{})) { 70 entry, _ := provider.loadOrInit(actorName) 71 if eventIndexEnd == 0 { 72 eventIndexEnd = len(entry.events) 73 } 74 for _, e := range entry.events[eventIndexStart:eventIndexEnd] { 75 callback(e) 76 } 77 } 78 79 func (provider *InMemoryProvider) PersistEvent(actorName string, eventIndex int, event proto.Message) { 80 entry, _ := provider.loadOrInit(actorName) 81 entry.events = append(entry.events, event) 82 } 83 84 func (provider *InMemoryProvider) DeleteEvents(actorName string, inclusiveToIndex int) { 85 }