package main import "sync" type RemoteGrainPool struct { mu sync.RWMutex Host string grains map[CartId]*RemoteGrain } func NewRemoteGrainPool(addr string) *RemoteGrainPool { return &RemoteGrainPool{ Host: addr, grains: make(map[CartId]*RemoteGrain), } } func (p *RemoteGrainPool) findRemoteGrain(id CartId) *RemoteGrain { p.mu.RLock() grain, ok := p.grains[id] p.mu.RUnlock() if !ok { return nil } return grain } func (p *RemoteGrainPool) findOrCreateGrain(id CartId) (*RemoteGrain, error) { grain := p.findRemoteGrain(id) if grain == nil { grain, err := NewRemoteGrain(id, p.Host) if err != nil { return nil, err } p.mu.Lock() p.grains[id] = grain p.mu.Unlock() } return grain, nil } func (p *RemoteGrainPool) Delete(id CartId) { p.mu.Lock() delete(p.grains, id) p.mu.Unlock() } func (p *RemoteGrainPool) Process(id CartId, messages ...Message) (*FrameWithPayload, error) { var result *FrameWithPayload grain, err := p.findOrCreateGrain(id) if err != nil { return nil, err } for _, message := range messages { result, err = grain.HandleMessage(&message, false) } return result, err } func (p *RemoteGrainPool) Get(id CartId) (*FrameWithPayload, error) { grain, err := p.findOrCreateGrain(id) if err != nil { return nil, err } return grain.GetCurrentState() }