mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
beacon/light: simplified Module interface
This commit is contained in:
parent
30bdde91ae
commit
c163cbdfc2
4 changed files with 130 additions and 131 deletions
|
|
@ -47,8 +47,7 @@ type Module interface {
|
|||
// Note: Process functions of different modules are never called concurrently;
|
||||
// they are called by Scheduler in the same order of priority as they were
|
||||
// registered in.
|
||||
HandleEvent(Event)
|
||||
Process()
|
||||
Process([]Event)
|
||||
MakeRequest(Server) (Request, float32)
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +66,8 @@ type Scheduler struct {
|
|||
|
||||
pending map[ServerAndID]pendingRequest
|
||||
eventLock sync.Mutex
|
||||
events []Event
|
||||
serverEvents []Event
|
||||
requestEvents map[Module][]Event
|
||||
stopCh chan chan struct{}
|
||||
|
||||
triggerCh chan struct{} // restarts waiting sync loop
|
||||
|
|
@ -150,12 +150,16 @@ func (s *Scheduler) RegisterServer(rs requestServer) {
|
|||
defer s.lock.Unlock()
|
||||
|
||||
server := newServer(rs, s.clock)
|
||||
s.servers[server] = struct{}{}
|
||||
s.eventLock.Lock()
|
||||
s.addEvent(Event{Type: EvRegistered, Server: server})
|
||||
s.eventLock.Unlock()
|
||||
server.subscribe(func(event Event) {
|
||||
event.Server = server
|
||||
s.eventLock.Lock()
|
||||
s.addEvent(event)
|
||||
s.eventLock.Unlock()
|
||||
})
|
||||
s.servers[server] = struct{}{}
|
||||
}
|
||||
|
||||
// UnregisterServer removes a registered server.
|
||||
|
|
@ -166,8 +170,10 @@ func (s *Scheduler) UnregisterServer(rs requestServer) {
|
|||
for server := range s.servers {
|
||||
if sl, ok := server.(*serverWithLimits); ok && sl.parent == rs {
|
||||
server.unsubscribe()
|
||||
delete(s.servers, server)
|
||||
s.eventLock.Lock()
|
||||
s.addEvent(Event{Type: EvUnregistered, Server: server})
|
||||
s.eventLock.Unlock()
|
||||
delete(s.servers, server)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +204,6 @@ func (s *Scheduler) Stop() {
|
|||
func (s *Scheduler) syncLoop() {
|
||||
for {
|
||||
s.lock.Lock()
|
||||
s.handleEvents()
|
||||
for {
|
||||
s.processModules()
|
||||
if !s.targetChanged() {
|
||||
|
|
@ -234,8 +239,15 @@ func (s *Scheduler) targetChanged() (changed bool) {
|
|||
// processModules runs an entire processing round, calling the Process functions
|
||||
// of all modules, passing all relevant events.
|
||||
func (s *Scheduler) processModules() {
|
||||
s.eventLock.Lock()
|
||||
serverEvents, requestEvents := s.serverEvents, s.requestEvents
|
||||
s.serverEvents, s.requestEvents = nil, nil
|
||||
s.eventLock.Unlock()
|
||||
|
||||
log.Debug("Processing modules", "server events", len(s.serverEvents))
|
||||
for _, module := range s.modules {
|
||||
module.Process()
|
||||
log.Debug("Processing module", "name", s.names[module], "request events", len(s.requestEvents[module]))
|
||||
module.Process(append(serverEvents, requestEvents[module]...))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,15 +258,16 @@ func (s *Scheduler) sendRequests() {
|
|||
servers[server] = struct{}{}
|
||||
}
|
||||
}
|
||||
log.Debug("Processing modules", "servers", len(servers))
|
||||
log.Debug("Generating request candidates", "servers", len(servers))
|
||||
|
||||
for _, module := range s.modules {
|
||||
for {
|
||||
if len(servers) == 0 {
|
||||
return
|
||||
}
|
||||
s.eventLock.Lock() // ensure that EvRequest is added first
|
||||
if req, sent := s.tryRequest(module, servers); sent {
|
||||
module.HandleEvent(Event{
|
||||
log.Debug("Sent request", "module", s.names[module])
|
||||
s.addEvent(Event{
|
||||
Type: EvRequest,
|
||||
Server: req.Server,
|
||||
Data: RequestResponse{
|
||||
|
|
@ -262,10 +275,8 @@ func (s *Scheduler) sendRequests() {
|
|||
Request: req.Request,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
s.eventLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -314,38 +325,21 @@ func (s *Scheduler) Trigger() {
|
|||
}
|
||||
}
|
||||
|
||||
// addEvent adds an Event either as a request event or a server event, depending
|
||||
// on its type. In case of an EvUnregistered server event it also closes all
|
||||
// pending requests to the given server by adding a failed request event (EvFail),
|
||||
// ensuring that all requests get finalized and thereby allowing the module logic
|
||||
// to be safe and simple.
|
||||
func (s *Scheduler) addEvent(event Event) {
|
||||
s.eventLock.Lock()
|
||||
s.events = append(s.events, event)
|
||||
if _, ok := s.servers[event.Server.(server)]; !ok {
|
||||
return
|
||||
}
|
||||
s.Trigger()
|
||||
s.eventLock.Unlock()
|
||||
}
|
||||
|
||||
func (s *Scheduler) handleEvents() {
|
||||
s.eventLock.Lock()
|
||||
events := s.events
|
||||
s.events = nil
|
||||
s.eventLock.Unlock()
|
||||
for _, event := range events {
|
||||
if _, ok := s.servers[event.Server.(server)]; ok {
|
||||
s.handleEvent(event)
|
||||
} else {
|
||||
log.Error("Event received from unsubscribed server")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handleEvent processes an Event and adds it either as a request event or a
|
||||
// server event, depending on its type. In case of an EvUnregistered server event
|
||||
// it also closes all pending requests to the given server by emitting a failed
|
||||
// request event (EvFail), ensuring that all requests get finalized and thereby
|
||||
// allowing the module logic to be safe and simple.
|
||||
func (s *Scheduler) handleEvent(event Event) {
|
||||
if event.IsRequestEvent() {
|
||||
sid, _, _ := event.RequestInfo()
|
||||
if pr, ok := s.pending[sid]; ok {
|
||||
pr.module.HandleEvent(event)
|
||||
if event.Type != EvTimeout {
|
||||
s.addRequestEvent(pr.module, event)
|
||||
if event.Type == EvResponse || event.Type == EvFail {
|
||||
delete(s.pending, sid)
|
||||
}
|
||||
}
|
||||
|
|
@ -356,7 +350,7 @@ func (s *Scheduler) handleEvent(event Event) {
|
|||
if id.Server != event.Server {
|
||||
continue
|
||||
}
|
||||
pending.module.HandleEvent(Event{
|
||||
s.addRequestEvent(pending.module, Event{
|
||||
Type: EvFail,
|
||||
Server: event.Server,
|
||||
Data: RequestResponse{
|
||||
|
|
@ -366,7 +360,12 @@ func (s *Scheduler) handleEvent(event Event) {
|
|||
})
|
||||
}
|
||||
}
|
||||
for _, module := range s.modules {
|
||||
module.HandleEvent(event)
|
||||
s.serverEvents = append(s.serverEvents, event)
|
||||
}
|
||||
|
||||
func (s *Scheduler) addRequestEvent(module Module, event Event) {
|
||||
if s.requestEvents == nil {
|
||||
s.requestEvents = make(map[Module][]Event)
|
||||
}
|
||||
s.requestEvents[module] = append(s.requestEvents[module], event)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ func NewHeadSync(headTracker headTracker, chain committeeChain) *HeadSync {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *HeadSync) HandleEvent(event request.Event) {
|
||||
func (s *HeadSync) Process(events []request.Event) {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case EvNewHead:
|
||||
s.setServerHead(event.Server, event.Data.(types.HeadInfo))
|
||||
|
|
@ -80,7 +81,6 @@ func (s *HeadSync) HandleEvent(event request.Event) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *HeadSync) Process() {
|
||||
nextPeriod, chainInit := s.chain.NextSyncPeriod()
|
||||
if nextPeriod != s.nextSyncPeriod || chainInit != s.chainInit {
|
||||
s.nextSyncPeriod, s.chainInit = nextPeriod, chainInit
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ func NewCheckpointInit(chain committeeChain, checkpointHash common.Hash) *Checkp
|
|||
}
|
||||
}
|
||||
|
||||
func (s *CheckpointInit) HandleEvent(event request.Event) {
|
||||
func (s *CheckpointInit) Process(events []request.Event) {
|
||||
for _, event := range events {
|
||||
if !event.IsRequestEvent() {
|
||||
return
|
||||
}
|
||||
|
|
@ -73,8 +74,7 @@ func (s *CheckpointInit) HandleEvent(event request.Event) {
|
|||
event.Server.Fail("invalid checkpoint data")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CheckpointInit) Process() {}
|
||||
}
|
||||
|
||||
func (s *CheckpointInit) MakeRequest(server request.Server) (request.Request, float32) {
|
||||
if s.initialized || s.locked != (request.ServerAndID{}) {
|
||||
|
|
@ -226,7 +226,8 @@ func (u updateResponseList) Less(i, j int) bool {
|
|||
u[j].Data.(request.RequestResponse).Request.(ReqUpdates).FirstPeriod
|
||||
}
|
||||
|
||||
func (s *ForwardUpdateSync) HandleEvent(event request.Event) {
|
||||
func (s *ForwardUpdateSync) Process(events []request.Event) {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case request.EvRequest:
|
||||
sid, req, _ := event.RequestInfo()
|
||||
|
|
@ -252,7 +253,6 @@ func (s *ForwardUpdateSync) HandleEvent(event request.Event) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *ForwardUpdateSync) Process() {
|
||||
// try processing ordered list of available responses
|
||||
sort.Sort(updateResponseList(s.processQueue)) //TODO
|
||||
for s.processQueue != nil {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ func newBeaconBlockSync(headTracker headTracker) *beaconBlockSync {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *beaconBlockSync) HandleEvent(event request.Event) {
|
||||
func (s *beaconBlockSync) Process(events []request.Event) {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case request.EvRequest:
|
||||
_, req, _ := event.RequestInfo()
|
||||
|
|
@ -74,7 +75,6 @@ func (s *beaconBlockSync) HandleEvent(event request.Event) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *beaconBlockSync) Process() {
|
||||
// send validated head block
|
||||
if vh := s.headTracker.ValidatedHead(); vh != (types.SignedHeader{}) {
|
||||
validatedHead := vh.Header.Hash()
|
||||
|
|
|
|||
Loading…
Reference in a new issue