github.com/Cloud-Foundations/Dominator@v0.3.4/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) 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; { 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 count++ 40 numToFlush++ 41 flushTimer.Reset(flushDelay) 42 case <-flushTimer.C: 43 if numToFlush > 1 { 44 t.logger.Debugf(0, "flushing %d events\n", numToFlush) 45 } 46 numToFlush = 0 47 if err := conn.Flush(); err != nil { 48 t.logger.Printf("error flushing update(s): %s\n", err) 49 return err 50 } 51 case err := <-closeChannel: 52 if err == nil { 53 t.logger.Debugf(0, "update client disconnected: %s\n", 54 conn.RemoteAddr()) 55 return nil 56 } 57 t.logger.Println(err) 58 return err 59 } 60 } 61 return nil 62 }