github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/fleetmanager/rpcd/getUpdates.go (about) 1 package rpcd 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/Cloud-Foundations/Dominator/lib/srpc" 8 proto "github.com/Cloud-Foundations/Dominator/proto/fleetmanager" 9 ) 10 11 const flushDelay = time.Millisecond * 10 12 13 func (t *srpcType) GetUpdates(conn *srpc.Conn) error { 14 var request proto.GetUpdatesRequest 15 if err := conn.Decode(&request); err != nil { 16 return err 17 } 18 closeChannel := conn.GetCloseNotifier() 19 updateChannel := t.hypervisorsManager.MakeUpdateChannel(request.Location) 20 defer t.hypervisorsManager.CloseUpdateChannel(updateChannel) 21 flushTimer := time.NewTimer(flushDelay) 22 var numToFlush uint 23 maxUpdates := request.MaxUpdates 24 for count := uint64(0); maxUpdates < 1 || count < maxUpdates; count++ { 25 select { 26 case update, ok := <-updateChannel: 27 if !ok { 28 err := errors.New("receiver not keeping up with updates") 29 t.logger.Printf("error sending update: %s\n", err) 30 return err 31 } 32 if err := conn.Encode(update); err != nil { 33 t.logger.Printf("error sending update: %s\n", err) 34 return err 35 } 36 if update.Error != "" { 37 return nil 38 } 39 numToFlush++ 40 flushTimer.Reset(flushDelay) 41 case <-flushTimer.C: 42 if numToFlush > 1 { 43 t.logger.Debugf(0, "flushing %d events\n", numToFlush) 44 } 45 numToFlush = 0 46 if err := conn.Flush(); err != nil { 47 t.logger.Printf("error flushing update(s): %s\n", err) 48 return err 49 } 50 case err := <-closeChannel: 51 if err == nil { 52 t.logger.Debugf(0, "update client disconnected: %s\n", 53 conn.RemoteAddr()) 54 return nil 55 } 56 t.logger.Println(err) 57 return err 58 } 59 } 60 return nil 61 }