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  }