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  }