github.com/livekit/protocol@v1.39.3/rpc/typed_api.go (about)

     1  // Copyright 2023 LiveKit, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package rpc
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"time"
    21  
    22  	"github.com/livekit/protocol/livekit"
    23  	"github.com/livekit/protocol/logger"
    24  	"github.com/livekit/protocol/utils/must"
    25  	"github.com/livekit/psrpc"
    26  	"github.com/livekit/psrpc/pkg/middleware"
    27  )
    28  
    29  type PSRPCConfig struct {
    30  	MaxAttempts int           `yaml:"max_attempts,omitempty"`
    31  	Timeout     time.Duration `yaml:"timeout,omitempty"`
    32  	Backoff     time.Duration `yaml:"backoff,omitempty"`
    33  	BufferSize  int           `yaml:"buffer_size,omitempty"`
    34  }
    35  
    36  var DefaultPSRPCConfig = PSRPCConfig{
    37  	MaxAttempts: 3,
    38  	Timeout:     3 * time.Second,
    39  	Backoff:     2 * time.Second,
    40  	BufferSize:  1000,
    41  }
    42  
    43  type ClientParams struct {
    44  	PSRPCConfig
    45  	Bus      psrpc.MessageBus
    46  	Logger   logger.Logger
    47  	Observer middleware.MetricsObserver
    48  }
    49  
    50  func NewClientParams(
    51  	config PSRPCConfig,
    52  	bus psrpc.MessageBus,
    53  	logger logger.Logger,
    54  	observer middleware.MetricsObserver,
    55  ) ClientParams {
    56  	return ClientParams{
    57  		PSRPCConfig: config,
    58  		Bus:         bus,
    59  		Logger:      logger,
    60  		Observer:    observer,
    61  	}
    62  }
    63  
    64  func (p *ClientParams) Options() []psrpc.ClientOption {
    65  	opts := make([]psrpc.ClientOption, 0, 4)
    66  	if p.BufferSize != 0 {
    67  		opts = append(opts, psrpc.WithClientChannelSize(p.BufferSize))
    68  	}
    69  	if p.Observer != nil {
    70  		opts = append(opts, middleware.WithClientMetrics(p.Observer))
    71  	}
    72  	if p.Logger != nil {
    73  		opts = append(opts, WithClientLogger(p.Logger))
    74  	}
    75  	if p.MaxAttempts != 0 || p.Timeout != 0 || p.Backoff != 0 {
    76  		opts = append(opts, middleware.WithRPCRetries(middleware.RetryOptions{
    77  			MaxAttempts: p.MaxAttempts,
    78  			Timeout:     p.Timeout,
    79  			Backoff:     p.Backoff,
    80  		}))
    81  	}
    82  	return opts
    83  }
    84  
    85  func (p *ClientParams) Args() (psrpc.MessageBus, psrpc.ClientOption) {
    86  	return p.Bus, psrpc.WithClientOptions(p.Options()...)
    87  }
    88  
    89  func WithServerObservability(logger logger.Logger) psrpc.ServerOption {
    90  	return psrpc.WithServerOptions(
    91  		middleware.WithServerMetrics(PSRPCMetricsObserver{}),
    92  		WithServerLogger(logger),
    93  	)
    94  }
    95  
    96  func WithDefaultServerOptions(psrpcConfig PSRPCConfig, logger logger.Logger) psrpc.ServerOption {
    97  	return psrpc.WithServerOptions(
    98  		psrpc.WithServerChannelSize(psrpcConfig.BufferSize),
    99  		WithServerObservability(logger),
   100  	)
   101  }
   102  
   103  func WithClientObservability(logger logger.Logger) psrpc.ClientOption {
   104  	return psrpc.WithClientOptions(
   105  		middleware.WithClientMetrics(PSRPCMetricsObserver{}),
   106  		WithClientLogger(logger),
   107  	)
   108  }
   109  
   110  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
   111  
   112  type TypedSignalClient = SignalClient[livekit.NodeID]
   113  type TypedSignalServer = SignalServer[livekit.NodeID]
   114  
   115  func NewTypedSignalClient(nodeID livekit.NodeID, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (TypedSignalClient, error) {
   116  	return NewSignalClient[livekit.NodeID](bus, psrpc.WithClientOptions(opts...), psrpc.WithClientID(string(nodeID)))
   117  }
   118  
   119  func NewTypedSignalServer(nodeID livekit.NodeID, svc SignalServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedSignalServer, error) {
   120  	return NewSignalServer[livekit.NodeID](svc, bus, psrpc.WithServerOptions(opts...), psrpc.WithServerID(string(nodeID)))
   121  }
   122  
   123  type TypedRoomManagerClient = RoomManagerClient[livekit.NodeID]
   124  type TypedRoomManagerServer = RoomManagerServer[livekit.NodeID]
   125  
   126  func NewTypedRoomManagerClient(bus psrpc.MessageBus, opts ...psrpc.ClientOption) (TypedRoomManagerClient, error) {
   127  	return NewRoomManagerClient[livekit.NodeID](bus, opts...)
   128  }
   129  
   130  func NewTypedRoomManagerServer(svc RoomManagerServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedRoomManagerServer, error) {
   131  	return NewRoomManagerServer[livekit.NodeID](svc, bus, opts...)
   132  }
   133  
   134  type ParticipantTopic string
   135  type RoomTopic string
   136  
   137  func FormatParticipantTopic(roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic {
   138  	return ParticipantTopic(fmt.Sprintf("%s_%s", roomName, identity))
   139  }
   140  
   141  func FormatRoomTopic(roomName livekit.RoomName) RoomTopic {
   142  	return RoomTopic(roomName)
   143  }
   144  
   145  type topicFormatter struct{}
   146  
   147  func NewTopicFormatter() TopicFormatter {
   148  	return topicFormatter{}
   149  }
   150  
   151  func (f topicFormatter) ParticipantTopic(ctx context.Context, roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic {
   152  	return FormatParticipantTopic(roomName, identity)
   153  }
   154  
   155  func (f topicFormatter) RoomTopic(ctx context.Context, roomName livekit.RoomName) RoomTopic {
   156  	return FormatRoomTopic(roomName)
   157  }
   158  
   159  type TopicFormatter interface {
   160  	ParticipantTopic(ctx context.Context, roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic
   161  	RoomTopic(ctx context.Context, roomName livekit.RoomName) RoomTopic
   162  }
   163  
   164  //counterfeiter:generate . TypedRoomClient
   165  type TypedRoomClient = RoomClient[RoomTopic]
   166  type TypedRoomServer = RoomServer[RoomTopic]
   167  
   168  func NewTypedRoomClient(params ClientParams) (TypedRoomClient, error) {
   169  	return NewRoomClient[RoomTopic](params.Args())
   170  }
   171  
   172  func NewTypedRoomServer(svc RoomServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedRoomServer, error) {
   173  	return NewRoomServer[RoomTopic](svc, bus, opts...)
   174  }
   175  
   176  //counterfeiter:generate . TypedParticipantClient
   177  type TypedParticipantClient = ParticipantClient[ParticipantTopic]
   178  type TypedParticipantServer = ParticipantServer[ParticipantTopic]
   179  
   180  func NewTypedParticipantClient(params ClientParams) (TypedParticipantClient, error) {
   181  	return NewParticipantClient[ParticipantTopic](params.Args())
   182  }
   183  
   184  func NewTypedParticipantServer(svc ParticipantServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedParticipantServer, error) {
   185  	return NewParticipantServer[ParticipantTopic](svc, bus, opts...)
   186  }
   187  
   188  //counterfeiter:generate . TypedRTCRestParticipantClient
   189  type TypedRTCRestParticipantClient = RTCRestParticipantClient[ParticipantTopic]
   190  type TypedRTCRestParticipantServer = RTCRestParticipantServer[ParticipantTopic]
   191  
   192  func NewTypedRTCRestParticipantClient(params ClientParams) (TypedRTCRestParticipantClient, error) {
   193  	return NewRTCRestParticipantClient[ParticipantTopic](params.Args())
   194  }
   195  
   196  func NewTypedRTCRestParticipantServer(svc RTCRestParticipantServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedRTCRestParticipantServer, error) {
   197  	return NewRTCRestParticipantServer[ParticipantTopic](svc, bus, opts...)
   198  }
   199  
   200  //counterfeiter:generate . TypedAgentDispatchInternalClient
   201  type TypedAgentDispatchInternalClient = AgentDispatchInternalClient[RoomTopic]
   202  type TypedAgentDispatchInternalServer = AgentDispatchInternalServer[RoomTopic]
   203  
   204  func NewTypedAgentDispatchInternalClient(params ClientParams) (TypedAgentDispatchInternalClient, error) {
   205  	return NewAgentDispatchInternalClient[RoomTopic](params.Args())
   206  }
   207  
   208  func NewTypedAgentDispatchInternalServer(svc AgentDispatchInternalServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedAgentDispatchInternalServer, error) {
   209  	return NewAgentDispatchInternalServer[RoomTopic](svc, bus, opts...)
   210  }
   211  
   212  //counterfeiter:generate . KeepalivePubSub
   213  type KeepalivePubSub interface {
   214  	KeepaliveClient[livekit.NodeID]
   215  	KeepaliveServer[livekit.NodeID]
   216  }
   217  
   218  type keepalivePubSub struct {
   219  	KeepaliveClient[livekit.NodeID]
   220  	KeepaliveServer[livekit.NodeID]
   221  }
   222  
   223  func NewKeepalivePubSub(params ClientParams) (KeepalivePubSub, error) {
   224  	client, err := NewKeepaliveClient[livekit.NodeID](params.Args())
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  	server := must.Get(NewKeepaliveServer[livekit.NodeID](nil, params.Bus))
   229  	return &keepalivePubSub{client, server}, nil
   230  }