github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/hypervisor/rpcd/traceVmMetadata.go (about) 1 package rpcd 2 3 import ( 4 "time" 5 6 "github.com/Cloud-Foundations/Dominator/lib/errors" 7 "github.com/Cloud-Foundations/Dominator/lib/srpc" 8 "github.com/Cloud-Foundations/Dominator/proto/hypervisor" 9 ) 10 11 func (t *srpcType) TraceVmMetadata(conn *srpc.Conn) error { 12 var request hypervisor.TraceVmMetadataRequest 13 if err := conn.Decode(&request); err != nil { 14 return err 15 } 16 pathChannel := make(chan string, 1024) 17 err := t.manager.RegisterVmMetadataNotifier(request.IpAddress, 18 conn.GetAuthInformation(), pathChannel) 19 if err == nil { 20 defer func() { 21 t.manager.UnregisterVmMetadataNotifier(request.IpAddress, 22 pathChannel) 23 }() 24 } 25 var response hypervisor.TraceVmMetadataResponse 26 response.Error = errors.ErrorToString(err) 27 if err := conn.Encode(response); err != nil { 28 return err 29 } 30 if err := conn.Flush(); err != nil { 31 return err 32 } 33 if err != nil { 34 return nil 35 } 36 closeChannel := conn.GetCloseNotifier() 37 flushDelay := time.Millisecond * 100 38 flushTimer := time.NewTimer(flushDelay) 39 for { 40 select { 41 case path, ok := <-pathChannel: 42 if !ok { 43 _, err := conn.Write([]byte("VM destroyed\n\n")) 44 return err 45 } 46 if _, err := conn.Write([]byte(path + "\n")); err != nil { 47 return err 48 } 49 flushTimer.Reset(flushDelay) 50 case <-flushTimer.C: 51 if err := conn.Flush(); err != nil { 52 return err 53 } 54 case err := <-closeChannel: 55 if err == nil { 56 t.logger.Debugf(0, "metadata trace client disconnected: %s\n", 57 conn.RemoteAddr()) 58 return nil 59 } 60 t.logger.Println(err) 61 return err 62 } 63 } 64 }