github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/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  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
    86  
    87  type TypedSignalClient = SignalClient[livekit.NodeID]
    88  type TypedSignalServer = SignalServer[livekit.NodeID]
    89  
    90  func NewTypedSignalClient(nodeID livekit.NodeID, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (TypedSignalClient, error) {
    91  	return NewSignalClient[livekit.NodeID](bus, append(opts[:len(opts):len(opts)], psrpc.WithClientID(string(nodeID)))...)
    92  }
    93  
    94  func NewTypedSignalServer(nodeID livekit.NodeID, svc SignalServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedSignalServer, error) {
    95  	return NewSignalServer[livekit.NodeID](svc, bus, append(opts[:len(opts):len(opts)], psrpc.WithServerID(string(nodeID)))...)
    96  }
    97  
    98  type ParticipantTopic string
    99  type RoomTopic string
   100  
   101  func FormatParticipantTopic(roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic {
   102  	return ParticipantTopic(fmt.Sprintf("%s_%s", roomName, identity))
   103  }
   104  
   105  func FormatRoomTopic(roomName livekit.RoomName) RoomTopic {
   106  	return RoomTopic(roomName)
   107  }
   108  
   109  type topicFormatter struct{}
   110  
   111  func NewTopicFormatter() TopicFormatter {
   112  	return topicFormatter{}
   113  }
   114  
   115  func (f topicFormatter) ParticipantTopic(ctx context.Context, roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic {
   116  	return FormatParticipantTopic(roomName, identity)
   117  }
   118  
   119  func (f topicFormatter) RoomTopic(ctx context.Context, roomName livekit.RoomName) RoomTopic {
   120  	return FormatRoomTopic(roomName)
   121  }
   122  
   123  type TopicFormatter interface {
   124  	ParticipantTopic(ctx context.Context, roomName livekit.RoomName, identity livekit.ParticipantIdentity) ParticipantTopic
   125  	RoomTopic(ctx context.Context, roomName livekit.RoomName) RoomTopic
   126  }
   127  
   128  //counterfeiter:generate . TypedRoomClient
   129  type TypedRoomClient = RoomClient[RoomTopic]
   130  type TypedRoomServer = RoomServer[RoomTopic]
   131  
   132  func NewTypedRoomClient(params ClientParams) (TypedRoomClient, error) {
   133  	return NewRoomClient[RoomTopic](params.Bus, params.Options()...)
   134  }
   135  
   136  func NewTypedRoomServer(svc RoomServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedRoomServer, error) {
   137  	return NewRoomServer[RoomTopic](svc, bus, opts...)
   138  }
   139  
   140  //counterfeiter:generate . TypedParticipantClient
   141  type TypedParticipantClient = ParticipantClient[ParticipantTopic]
   142  type TypedParticipantServer = ParticipantServer[ParticipantTopic]
   143  
   144  func NewTypedParticipantClient(params ClientParams) (TypedParticipantClient, error) {
   145  	return NewParticipantClient[ParticipantTopic](params.Bus, params.Options()...)
   146  }
   147  
   148  func NewTypedParticipantServer(svc ParticipantServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (TypedParticipantServer, error) {
   149  	return NewParticipantServer[ParticipantTopic](svc, bus, opts...)
   150  }
   151  
   152  //counterfeiter:generate . KeepalivePubSub
   153  type KeepalivePubSub interface {
   154  	KeepaliveClient[livekit.NodeID]
   155  	KeepaliveServer[livekit.NodeID]
   156  }
   157  
   158  type keepalivePubSub struct {
   159  	KeepaliveClient[livekit.NodeID]
   160  	KeepaliveServer[livekit.NodeID]
   161  }
   162  
   163  func NewKeepalivePubSub(params ClientParams) (KeepalivePubSub, error) {
   164  	client, err := NewKeepaliveClient[livekit.NodeID](params.Bus, params.Options()...)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	server := must.Get(NewKeepaliveServer[livekit.NodeID](nil, params.Bus))
   169  	return &keepalivePubSub{client, server}, nil
   170  }