blob: 5f9b0317d5e048e30274b429389dd64807d2cd03 [file] [edit]
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package server provides functionality for running a gRPC server that serves
// the BtpeerManagementService.
package server
import (
"context"
"fmt"
"log/slog"
"net"
"go.chromium.org/chromiumos/config/go/test/lab/api/btpeerd"
"go.chromium.org/chromiumos/platform/btpeerd/core/exec"
"google.golang.org/grpc"
)
// RunGRPCServer starts a gRPC server on the specified system port.
// The server is stopped if the context expires. Will only return if the server
// has stopped. Returns a non-nil error if the server stopped on its own.
func RunGRPCServer(ctx context.Context, port int) error {
// Configure server.
var serverOpts []grpc.ServerOption
server := grpc.NewServer(serverOpts...)
runner := &exec.SystemCmdRunner{}
btpeerd.RegisterBtpeerManagementServiceServer(server, NewBtpeerManagementServiceServer(runner))
// Start server, stopping it if the ctx expires.
listenAddr := fmt.Sprintf("localhost:%d", port)
slog.Info("Starting gRPC server", "listenAddr", listenAddr)
lis, err := net.Listen("tcp", listenAddr)
if err != nil {
return fmt.Errorf("failed to listen on tcp port %d: %w", port, err)
}
slog.Debug("gRPC service info", "serviceInfo", server.GetServiceInfo())
serverChannel := make(chan error, 1)
go func() {
serverChannel <- server.Serve(lis)
}()
select {
case err := <-serverChannel:
return fmt.Errorf("grpc server error: %w", err)
case <-ctx.Done():
slog.Info("Stopping gRPC server gracefully")
server.GracefulStop()
return nil
}
}