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  }