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