github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/clusterproviders/zk/singleton.go (about) 1 package zk 2 3 import ( 4 "sync" 5 6 "github.com/asynkron/protoactor-go/actor" 7 ) 8 9 type SingletonScheduler struct { 10 sync.Mutex 11 root *actor.RootContext 12 props []*actor.Props 13 pids []*actor.PID 14 } 15 16 func NewSingletonScheduler(rc *actor.RootContext) *SingletonScheduler { 17 return &SingletonScheduler{root: rc} 18 } 19 20 func (s *SingletonScheduler) FromFunc(f actor.ReceiveFunc) *SingletonScheduler { 21 s.Lock() 22 defer s.Unlock() 23 s.props = append(s.props, actor.PropsFromFunc(f)) 24 return s 25 } 26 27 func (s *SingletonScheduler) FromProducer(f actor.Producer) *SingletonScheduler { 28 s.Lock() 29 defer s.Unlock() 30 s.props = append(s.props, actor.PropsFromProducer(f)) 31 return s 32 } 33 34 func (s *SingletonScheduler) OnRoleChanged(rt RoleType) { 35 36 s.Lock() 37 defer s.Unlock() 38 if rt == Follower { 39 if len(s.pids) > 0 { 40 s.root.Logger().Info("I am follower, poison singleton actors") 41 for _, pid := range s.pids { 42 s.root.Poison(pid) 43 } 44 s.pids = nil 45 } 46 } else if rt == Leader { 47 if len(s.props) > 0 { 48 s.root.Logger().Info("I am leader now, start singleton actors") 49 s.pids = make([]*actor.PID, len(s.props)) 50 for i, p := range s.props { 51 s.pids[i] = s.root.Spawn(p) 52 } 53 } 54 } 55 }