github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/plugins/device/server.go (about) 1 package device 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/golang/protobuf/ptypes" 9 "github.com/hashicorp/go-plugin" 10 11 "github.com/hashicorp/nomad/plugins/device/proto" 12 ) 13 14 // devicePluginServer wraps a device plugin and exposes it via gRPC. 15 type devicePluginServer struct { 16 broker *plugin.GRPCBroker 17 impl DevicePlugin 18 } 19 20 func (d *devicePluginServer) Fingerprint(req *proto.FingerprintRequest, stream proto.DevicePlugin_FingerprintServer) error { 21 ctx := stream.Context() 22 outCh, err := d.impl.Fingerprint(ctx) 23 if err != nil { 24 return err 25 } 26 27 for { 28 select { 29 case <-ctx.Done(): 30 return nil 31 case resp, ok := <-outCh: 32 // The output channel has been closed, end the stream 33 if !ok { 34 return nil 35 } 36 37 // Handle any error 38 if resp.Error != nil { 39 return resp.Error 40 } 41 42 // Convert the devices 43 out := convertStructDeviceGroups(resp.Devices) 44 45 // Build the response 46 presp := &proto.FingerprintResponse{ 47 DeviceGroup: out, 48 } 49 50 // Send the devices 51 if err := stream.Send(presp); err != nil { 52 return err 53 } 54 } 55 } 56 } 57 58 func (d *devicePluginServer) Reserve(ctx context.Context, req *proto.ReserveRequest) (*proto.ReserveResponse, error) { 59 resp, err := d.impl.Reserve(req.GetDeviceIds()) 60 if err != nil { 61 return nil, err 62 } 63 64 // Make the response 65 presp := &proto.ReserveResponse{ 66 ContainerRes: convertStructContainerReservation(resp), 67 } 68 69 return presp, nil 70 } 71 72 func (d *devicePluginServer) Stats(req *proto.StatsRequest, stream proto.DevicePlugin_StatsServer) error { 73 ctx := stream.Context() 74 75 // Retrieve the collection interval 76 interval, err := ptypes.Duration(req.CollectionInterval) 77 if err != nil { 78 return fmt.Errorf("failed to parse collection interval: %v", err) 79 } 80 81 // Default the duration if we get an invalid duration 82 if interval.Nanoseconds() == 0 { 83 interval = time.Second 84 } 85 86 outCh, err := d.impl.Stats(ctx, interval) 87 if err != nil { 88 return err 89 } 90 91 for { 92 select { 93 case <-ctx.Done(): 94 return nil 95 case resp, ok := <-outCh: 96 // The output channel has been closed, end the stream 97 if !ok { 98 return nil 99 } 100 101 // Handle any error 102 if resp.Error != nil { 103 return resp.Error 104 } 105 106 // Convert the devices 107 out := convertStructDeviceGroupsStats(resp.Groups) 108 109 // Build the response 110 presp := &proto.StatsResponse{ 111 Groups: out, 112 } 113 114 // Send the devices 115 if err := stream.Send(presp); err != nil { 116 return err 117 } 118 } 119 } 120 }