diff --git a/.github/workflows/buildtest.yaml b/.github/workflows/buildtest.yaml index 02b996c0..6b499911 100644 --- a/.github/workflows/buildtest.yaml +++ b/.github/workflows/buildtest.yaml @@ -34,6 +34,7 @@ jobs: - name: Static Check uses: dominikh/staticcheck-action@v1.3.0 with: + checks: '["all", "-ST1000", "-ST1003", "-ST1020", "-ST1021", "-ST1022", "-SA1019"]' version: "2022.1.3" - name: Test diff --git a/.github/workflows/generate.yaml b/.github/workflows/generate.yaml index 7ed3a629..d31e1c1f 100644 --- a/.github/workflows/generate.yaml +++ b/.github/workflows/generate.yaml @@ -14,7 +14,6 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v1 with: - version: '3.x' repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Go @@ -30,6 +29,7 @@ jobs: go install github.com/twitchtv/twirp/protoc-gen-twirp@v8.1.3 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 + go install github.com/livekit/psrpc/protoc-gen-psrpc@v0.2.6 - name: Mage Test uses: magefile/mage-action@v2 diff --git a/egress/rpc.go b/egress/rpc.go index abaa5f44..c3398455 100644 --- a/egress/rpc.go +++ b/egress/rpc.go @@ -10,6 +10,7 @@ import ( "github.com/livekit/protocol/livekit" "github.com/livekit/protocol/logger" + "github.com/livekit/protocol/rpc" "github.com/livekit/protocol/utils" ) @@ -37,7 +38,7 @@ type RPCServer interface { // GetRequestChannel returns a subscription for egress requests GetRequestChannel(ctx context.Context) (utils.PubSub, error) // ClaimRequest is used to take ownership of a request - ClaimRequest(ctx context.Context, request *livekit.StartEgressRequest) (bool, error) + ClaimRequest(ctx context.Context, request *rpc.StartEgressRequest) (bool, error) // EgressSubscription subscribes to requests for a specific egress ID EgressSubscription(ctx context.Context, egressID string) (utils.PubSub, error) // SendResponse returns an RPC response @@ -72,7 +73,7 @@ func (r *RedisRPC) SendRequest(ctx context.Context, request proto.Message) (*liv var channel string switch req := request.(type) { - case *livekit.StartEgressRequest: + case *rpc.StartEgressRequest: if req.EgressId == "" { req.EgressId = utils.NewGuid(utils.EgressPrefix) } @@ -134,7 +135,7 @@ func (r *RedisRPC) GetRequestChannel(ctx context.Context) (utils.PubSub, error) return r.bus.Subscribe(ctx, newEgressChannel) } -func (r *RedisRPC) ClaimRequest(ctx context.Context, req *livekit.StartEgressRequest) (bool, error) { +func (r *RedisRPC) ClaimRequest(ctx context.Context, req *rpc.StartEgressRequest) (bool, error) { claimed, err := r.bus.Lock(ctx, requestChannel(req.EgressId), lockDuration) if err != nil || !claimed { return false, err @@ -152,7 +153,7 @@ func (r *RedisRPC) SendResponse(ctx context.Context, request proto.Message, info } switch req := request.(type) { - case *livekit.StartEgressRequest: + case *rpc.StartEgressRequest: res.RequestId = req.RequestId case *livekit.EgressRequest: res.RequestId = req.RequestId diff --git a/go.mod b/go.mod index c800365c..f640a745 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/go-logr/logr v1.2.3 github.com/jxskiss/base62 v1.1.0 github.com/lithammer/shortuuid/v4 v4.0.0 + github.com/livekit/psrpc v0.2.6 github.com/mackerelio/go-osstat v0.2.3 github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 github.com/pion/sdp/v3 v3.0.6 @@ -33,8 +34,16 @@ require ( github.com/eapache/queue v1.1.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.2.1 // indirect + github.com/lithammer/shortuuid/v3 v3.0.7 // indirect + github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/nats-io/jwt/v2 v2.3.0 // indirect + github.com/nats-io/nats.go v1.21.0 // indirect + github.com/nats-io/nkeys v0.3.0 // indirect + github.com/nats-io/nuid v1.0.1 // indirect github.com/pion/datachannel v1.5.5 // indirect github.com/pion/dtls/v2 v2.2.4 // indirect github.com/pion/ice/v2 v2.3.0 // indirect @@ -58,6 +67,7 @@ require ( golang.org/x/crypto v0.6.0 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/net v0.6.0 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/tools v0.5.0 // indirect diff --git a/go.sum b/go.sum index c40590e8..3ff8e8d8 100644 --- a/go.sum +++ b/go.sum @@ -139,6 +139,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -159,6 +160,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw= github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -168,14 +171,22 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= +github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c= github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y= +github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkDaKb5iXdynYrzB84ErPPO4LbRASk58= +github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= +github.com/livekit/psrpc v0.2.6 h1:cYrpYEwKEd6TRtF9fXYjVEJU2K0laF0uL0hNJg7pw/E= +github.com/livekit/psrpc v0.2.6/go.mod h1:2wtOo1F03vub2qIjx0rAPpVplg873670/LN08o/yopM= github.com/mackerelio/go-osstat v0.2.3 h1:jAMXD5erlDE39kdX2CU7YwCGRcxIO33u/p8+Fhe5dJw= github.com/mackerelio/go-osstat v0.2.3/go.mod h1:DQbPOnsss9JHIXgBStc/dnhhir3gbd3YH+Dbdi7ptMA= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 h1:9XE5ykDiC8eNSqIPkxx0EsV3kMX1oe4kQWRZjIgytUA= github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1/go.mod h1:qbKwBR+qQODzH2WD/s53mdgp/xVcXMlJb59GRFOp6Z4= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -183,6 +194,15 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= +github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= +github.com/nats-io/nats-server/v2 v2.9.8 h1:jgxZsv+A3Reb3MgwxaINcNq/za8xZInKhDg9Q0cGN1o= +github.com/nats-io/nats.go v1.21.0 h1:kQiWyQMMMIPjDR7NanrLhTnRUxWgU04yrzmYdq9JxCU= +github.com/nats-io/nats.go v1.21.0/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -310,6 +330,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= @@ -407,10 +428,12 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -476,6 +499,7 @@ golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/ingress/rpc.go b/ingress/rpc.go index a8d83025..263b8fc9 100644 --- a/ingress/rpc.go +++ b/ingress/rpc.go @@ -10,6 +10,7 @@ import ( "github.com/livekit/protocol/livekit" "github.com/livekit/protocol/logger" + "github.com/livekit/protocol/rpc" "github.com/livekit/protocol/utils" ) @@ -32,7 +33,7 @@ type RPCClient interface { // SendRequest sends a request to all available instances SendRequest(ctx context.Context, req *livekit.IngressRequest) (*livekit.IngressState, error) // SendResponse returns a GetIngressInfo response - SendGetIngressInfoResponse(ctx context.Context, req *livekit.GetIngressInfoRequest, resp *livekit.GetIngressInfoResponse, err error) error + SendGetIngressInfoResponse(ctx context.Context, req *rpc.GetIngressInfoRequest, resp *rpc.GetIngressInfoResponse, err error) error } // RPCServer is used by Ingress @@ -44,7 +45,7 @@ type RPCServer interface { // SendUpdate sends an ingress info update SendUpdate(ctx context.Context, ingressId string, state *livekit.IngressState) error // SendGetIngressInfoRequest sends a request to all available instances - SendGetIngressInfoRequest(ctx context.Context, req *livekit.GetIngressInfoRequest) (*livekit.GetIngressInfoResponse, error) + SendGetIngressInfoRequest(ctx context.Context, req *rpc.GetIngressInfoRequest) (*rpc.GetIngressInfoResponse, error) } type RPC interface { @@ -129,7 +130,7 @@ func (r *RedisRPC) SendRequest(ctx context.Context, req *livekit.IngressRequest) } } -func (r *RedisRPC) SendGetIngressInfoRequest(ctx context.Context, req *livekit.GetIngressInfoRequest) (*livekit.GetIngressInfoResponse, error) { +func (r *RedisRPC) SendGetIngressInfoRequest(ctx context.Context, req *rpc.GetIngressInfoRequest) (*rpc.GetIngressInfoResponse, error) { requestID := utils.NewGuid(utils.RPCPrefix) var channel string var err error @@ -138,7 +139,7 @@ func (r *RedisRPC) SendGetIngressInfoRequest(ctx context.Context, req *livekit.G req.SenderId = string(r.nodeID) req.SentAt = time.Now().UnixNano() channel = entityChannel - resp := &livekit.GetIngressInfoResponse{} + resp := &rpc.GetIngressInfoResponse{} _, err = r.sendRequest(ctx, requestID, channel, req, resp) if err != nil { @@ -166,7 +167,7 @@ func (r *RedisRPC) SendResponse(ctx context.Context, req *livekit.IngressRequest return r.bus.Publish(ctx, responseChannel(res.RequestId), res) } -func (r *RedisRPC) SendGetIngressInfoResponse(ctx context.Context, req *livekit.GetIngressInfoRequest, resp *livekit.GetIngressInfoResponse, err error) error { +func (r *RedisRPC) SendGetIngressInfoResponse(ctx context.Context, req *rpc.GetIngressInfoRequest, resp *rpc.GetIngressInfoResponse, err error) error { resp.RequestId = req.RequestId if err != nil { @@ -177,7 +178,7 @@ func (r *RedisRPC) SendGetIngressInfoResponse(ctx context.Context, req *livekit. } func (r *RedisRPC) SendUpdate(ctx context.Context, ingressId string, state *livekit.IngressState) error { - return r.bus.Publish(ctx, updateChannel, &livekit.UpdateIngressStateRequest{ + return r.bus.Publish(ctx, updateChannel, &rpc.UpdateIngressStateRequest{ IngressId: ingressId, State: state, }) diff --git a/livekit/livekit_rpc_internal.pb.go b/livekit/livekit_rpc_internal.pb.go index 6f30d357..8c8cda6e 100644 --- a/livekit/livekit_rpc_internal.pb.go +++ b/livekit/livekit_rpc_internal.pb.go @@ -20,175 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type StartEgressRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // request metadata - EgressId string `protobuf:"bytes,1,opt,name=egress_id,json=egressId,proto3" json:"egress_id,omitempty"` - RequestId string `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - SenderId string `protobuf:"bytes,10,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` - SentAt int64 `protobuf:"varint,4,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` - // request - // - // Types that are assignable to Request: - // - // *StartEgressRequest_RoomComposite - // *StartEgressRequest_TrackComposite - // *StartEgressRequest_Track - // *StartEgressRequest_Web - Request isStartEgressRequest_Request `protobuf_oneof:"request"` - // connection info - RoomId string `protobuf:"bytes,3,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` - Token string `protobuf:"bytes,8,opt,name=token,proto3" json:"token,omitempty"` - WsUrl string `protobuf:"bytes,9,opt,name=ws_url,json=wsUrl,proto3" json:"ws_url,omitempty"` -} - -func (x *StartEgressRequest) Reset() { - *x = StartEgressRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StartEgressRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StartEgressRequest) ProtoMessage() {} - -func (x *StartEgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StartEgressRequest.ProtoReflect.Descriptor instead. -func (*StartEgressRequest) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{0} -} - -func (x *StartEgressRequest) GetEgressId() string { - if x != nil { - return x.EgressId - } - return "" -} - -func (x *StartEgressRequest) GetRequestId() string { - if x != nil { - return x.RequestId - } - return "" -} - -func (x *StartEgressRequest) GetSenderId() string { - if x != nil { - return x.SenderId - } - return "" -} - -func (x *StartEgressRequest) GetSentAt() int64 { - if x != nil { - return x.SentAt - } - return 0 -} - -func (m *StartEgressRequest) GetRequest() isStartEgressRequest_Request { - if m != nil { - return m.Request - } - return nil -} - -func (x *StartEgressRequest) GetRoomComposite() *RoomCompositeEgressRequest { - if x, ok := x.GetRequest().(*StartEgressRequest_RoomComposite); ok { - return x.RoomComposite - } - return nil -} - -func (x *StartEgressRequest) GetTrackComposite() *TrackCompositeEgressRequest { - if x, ok := x.GetRequest().(*StartEgressRequest_TrackComposite); ok { - return x.TrackComposite - } - return nil -} - -func (x *StartEgressRequest) GetTrack() *TrackEgressRequest { - if x, ok := x.GetRequest().(*StartEgressRequest_Track); ok { - return x.Track - } - return nil -} - -func (x *StartEgressRequest) GetWeb() *WebEgressRequest { - if x, ok := x.GetRequest().(*StartEgressRequest_Web); ok { - return x.Web - } - return nil -} - -func (x *StartEgressRequest) GetRoomId() string { - if x != nil { - return x.RoomId - } - return "" -} - -func (x *StartEgressRequest) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *StartEgressRequest) GetWsUrl() string { - if x != nil { - return x.WsUrl - } - return "" -} - -type isStartEgressRequest_Request interface { - isStartEgressRequest_Request() -} - -type StartEgressRequest_RoomComposite struct { - RoomComposite *RoomCompositeEgressRequest `protobuf:"bytes,5,opt,name=room_composite,json=roomComposite,proto3,oneof"` -} - -type StartEgressRequest_TrackComposite struct { - TrackComposite *TrackCompositeEgressRequest `protobuf:"bytes,6,opt,name=track_composite,json=trackComposite,proto3,oneof"` -} - -type StartEgressRequest_Track struct { - Track *TrackEgressRequest `protobuf:"bytes,7,opt,name=track,proto3,oneof"` -} - -type StartEgressRequest_Web struct { - Web *WebEgressRequest `protobuf:"bytes,11,opt,name=web,proto3,oneof"` -} - -func (*StartEgressRequest_RoomComposite) isStartEgressRequest_Request() {} - -func (*StartEgressRequest_TrackComposite) isStartEgressRequest_Request() {} - -func (*StartEgressRequest_Track) isStartEgressRequest_Request() {} - -func (*StartEgressRequest_Web) isStartEgressRequest_Request() {} - +// Deprecated: Do not use. type EgressRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -210,7 +42,7 @@ type EgressRequest struct { func (x *EgressRequest) Reset() { *x = EgressRequest{} if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[1] + mi := &file_livekit_rpc_internal_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -223,7 +55,7 @@ func (x *EgressRequest) String() string { func (*EgressRequest) ProtoMessage() {} func (x *EgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[1] + mi := &file_livekit_rpc_internal_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -236,7 +68,7 @@ func (x *EgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressRequest.ProtoReflect.Descriptor instead. func (*EgressRequest) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{1} + return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{0} } func (x *EgressRequest) GetEgressId() string { @@ -297,6 +129,7 @@ func (*EgressRequest_UpdateStream) isEgressRequest_Request() {} func (*EgressRequest_Stop) isEgressRequest_Request() {} +// Deprecated: Do not use. type EgressResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -310,7 +143,7 @@ type EgressResponse struct { func (x *EgressResponse) Reset() { *x = EgressResponse{} if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[2] + mi := &file_livekit_rpc_internal_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -323,7 +156,7 @@ func (x *EgressResponse) String() string { func (*EgressResponse) ProtoMessage() {} func (x *EgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[2] + mi := &file_livekit_rpc_internal_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -336,7 +169,7 @@ func (x *EgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressResponse.ProtoReflect.Descriptor instead. func (*EgressResponse) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{2} + return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{1} } func (x *EgressResponse) GetInfo() *EgressInfo { @@ -361,6 +194,8 @@ func (x *EgressResponse) GetRequestId() string { } // service -> ingress notification of a change in the ingress configuration +// +// Deprecated: Do not use. type IngressRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -380,7 +215,7 @@ type IngressRequest struct { func (x *IngressRequest) Reset() { *x = IngressRequest{} if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[3] + mi := &file_livekit_rpc_internal_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -393,7 +228,7 @@ func (x *IngressRequest) String() string { func (*IngressRequest) ProtoMessage() {} func (x *IngressRequest) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[3] + mi := &file_livekit_rpc_internal_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -406,7 +241,7 @@ func (x *IngressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IngressRequest.ProtoReflect.Descriptor instead. func (*IngressRequest) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{3} + return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{2} } func (x *IngressRequest) GetIngressId() string { @@ -467,142 +302,7 @@ func (*IngressRequest_Update) isIngressRequest_Request() {} func (*IngressRequest_Delete) isIngressRequest_Request() {} -// Query an ingress info from an ingress ID or stream key -type GetIngressInfoRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IngressId string `protobuf:"bytes,1,opt,name=ingress_id,json=ingressId,proto3" json:"ingress_id,omitempty"` - StreamKey string `protobuf:"bytes,2,opt,name=stream_key,json=streamKey,proto3" json:"stream_key,omitempty"` - RequestId string `protobuf:"bytes,3,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - SenderId string `protobuf:"bytes,4,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` - SentAt int64 `protobuf:"varint,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` -} - -func (x *GetIngressInfoRequest) Reset() { - *x = GetIngressInfoRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetIngressInfoRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetIngressInfoRequest) ProtoMessage() {} - -func (x *GetIngressInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetIngressInfoRequest.ProtoReflect.Descriptor instead. -func (*GetIngressInfoRequest) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{4} -} - -func (x *GetIngressInfoRequest) GetIngressId() string { - if x != nil { - return x.IngressId - } - return "" -} - -func (x *GetIngressInfoRequest) GetStreamKey() string { - if x != nil { - return x.StreamKey - } - return "" -} - -func (x *GetIngressInfoRequest) GetRequestId() string { - if x != nil { - return x.RequestId - } - return "" -} - -func (x *GetIngressInfoRequest) GetSenderId() string { - if x != nil { - return x.SenderId - } - return "" -} - -func (x *GetIngressInfoRequest) GetSentAt() int64 { - if x != nil { - return x.SentAt - } - return 0 -} - -// Request to store an update to the ingress state ingress -> service -type UpdateIngressStateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IngressId string `protobuf:"bytes,1,opt,name=ingress_id,json=ingressId,proto3" json:"ingress_id,omitempty"` - State *IngressState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` -} - -func (x *UpdateIngressStateRequest) Reset() { - *x = UpdateIngressStateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateIngressStateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateIngressStateRequest) ProtoMessage() {} - -func (x *UpdateIngressStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateIngressStateRequest.ProtoReflect.Descriptor instead. -func (*UpdateIngressStateRequest) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{5} -} - -func (x *UpdateIngressStateRequest) GetIngressId() string { - if x != nil { - return x.IngressId - } - return "" -} - -func (x *UpdateIngressStateRequest) GetState() *IngressState { - if x != nil { - return x.State - } - return nil -} - +// Deprecated: Do not use. type IngressResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -616,7 +316,7 @@ type IngressResponse struct { func (x *IngressResponse) Reset() { *x = IngressResponse{} if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[6] + mi := &file_livekit_rpc_internal_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -629,7 +329,7 @@ func (x *IngressResponse) String() string { func (*IngressResponse) ProtoMessage() {} func (x *IngressResponse) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[6] + mi := &file_livekit_rpc_internal_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -642,7 +342,7 @@ func (x *IngressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IngressResponse.ProtoReflect.Descriptor instead. func (*IngressResponse) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{6} + return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{3} } func (x *IngressResponse) GetState() *IngressState { @@ -666,85 +366,6 @@ func (x *IngressResponse) GetRequestId() string { return "" } -type GetIngressInfoResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Info *IngressInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` - WsUrl string `protobuf:"bytes,3,opt,name=ws_url,json=wsUrl,proto3" json:"ws_url,omitempty"` - Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` - RequestId string `protobuf:"bytes,5,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` -} - -func (x *GetIngressInfoResponse) Reset() { - *x = GetIngressInfoResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_livekit_rpc_internal_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetIngressInfoResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetIngressInfoResponse) ProtoMessage() {} - -func (x *GetIngressInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_livekit_rpc_internal_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetIngressInfoResponse.ProtoReflect.Descriptor instead. -func (*GetIngressInfoResponse) Descriptor() ([]byte, []int) { - return file_livekit_rpc_internal_proto_rawDescGZIP(), []int{7} -} - -func (x *GetIngressInfoResponse) GetInfo() *IngressInfo { - if x != nil { - return x.Info - } - return nil -} - -func (x *GetIngressInfoResponse) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *GetIngressInfoResponse) GetWsUrl() string { - if x != nil { - return x.WsUrl - } - return "" -} - -func (x *GetIngressInfoResponse) GetError() string { - if x != nil { - return x.Error - } - return "" -} - -func (x *GetIngressInfoResponse) GetRequestId() string { - if x != nil { - return x.RequestId - } - return "" -} - var File_livekit_rpc_internal_proto protoreflect.FileDescriptor var file_livekit_rpc_internal_proto_rawDesc = []byte{ @@ -753,113 +374,56 @@ var file_livekit_rpc_internal_proto_rawDesc = []byte{ 0x76, 0x65, 0x6b, 0x69, 0x74, 0x1a, 0x14, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x5f, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xda, 0x03, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x67, - 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x4c, 0x0a, 0x0e, 0x72, - 0x6f, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, - 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, - 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, - 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, - 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x74, 0x72, - 0x61, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, - 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x12, - 0x2d, 0x0a, 0x03, 0x77, 0x65, 0x62, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, - 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x57, 0x65, 0x62, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x03, 0x77, 0x65, 0x62, 0x12, 0x17, - 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x15, 0x0a, - 0x06, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x77, - 0x73, 0x55, 0x72, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0xea, 0x01, 0x0a, 0x0d, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x0d, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, - 0x00, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, - 0x30, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x74, 0x6f, - 0x70, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0e, - 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, - 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, - 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xe8, 0x01, 0x0a, - 0x0e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x06, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6c, 0x69, 0x76, - 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x09, 0x0a, 0x07, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x49, - 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, - 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x65, - 0x6e, 0x74, 0x41, 0x74, 0x22, 0x67, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, - 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x73, 0x0a, - 0x0f, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, - 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x69, - 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x15, 0x0a, - 0x06, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x77, - 0x73, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x42, 0x46, 0x5a, 0x23, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, - 0xaa, 0x02, 0x0d, 0x4c, 0x69, 0x76, 0x65, 0x4b, 0x69, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0xea, 0x02, 0x0e, 0x4c, 0x69, 0x76, 0x65, 0x4b, 0x69, 0x74, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x22, 0xee, 0x01, 0x0a, 0x0d, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x43, 0x0a, + 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, + 0x73, 0x74, 0x6f, 0x70, 0x3a, 0x02, 0x18, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x72, 0x0a, 0x0e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x45, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xec, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x37, + 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, + 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a, 0x02, 0x18, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x77, 0x0a, 0x0f, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, + 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x3a, 0x02, 0x18, 0x01, 0x42, + 0x46, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, + 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x6c, + 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0xaa, 0x02, 0x0d, 0x4c, 0x69, 0x76, 0x65, 0x4b, 0x69, 0x74, + 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0xea, 0x02, 0x0e, 0x4c, 0x69, 0x76, 0x65, 0x4b, 0x69, 0x74, + 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -874,46 +438,31 @@ func file_livekit_rpc_internal_proto_rawDescGZIP() []byte { return file_livekit_rpc_internal_proto_rawDescData } -var file_livekit_rpc_internal_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_livekit_rpc_internal_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_livekit_rpc_internal_proto_goTypes = []interface{}{ - (*StartEgressRequest)(nil), // 0: livekit.StartEgressRequest - (*EgressRequest)(nil), // 1: livekit.EgressRequest - (*EgressResponse)(nil), // 2: livekit.EgressResponse - (*IngressRequest)(nil), // 3: livekit.IngressRequest - (*GetIngressInfoRequest)(nil), // 4: livekit.GetIngressInfoRequest - (*UpdateIngressStateRequest)(nil), // 5: livekit.UpdateIngressStateRequest - (*IngressResponse)(nil), // 6: livekit.IngressResponse - (*GetIngressInfoResponse)(nil), // 7: livekit.GetIngressInfoResponse - (*RoomCompositeEgressRequest)(nil), // 8: livekit.RoomCompositeEgressRequest - (*TrackCompositeEgressRequest)(nil), // 9: livekit.TrackCompositeEgressRequest - (*TrackEgressRequest)(nil), // 10: livekit.TrackEgressRequest - (*WebEgressRequest)(nil), // 11: livekit.WebEgressRequest - (*UpdateStreamRequest)(nil), // 12: livekit.UpdateStreamRequest - (*StopEgressRequest)(nil), // 13: livekit.StopEgressRequest - (*EgressInfo)(nil), // 14: livekit.EgressInfo - (*UpdateIngressRequest)(nil), // 15: livekit.UpdateIngressRequest - (*DeleteIngressRequest)(nil), // 16: livekit.DeleteIngressRequest - (*IngressState)(nil), // 17: livekit.IngressState - (*IngressInfo)(nil), // 18: livekit.IngressInfo + (*EgressRequest)(nil), // 0: livekit.EgressRequest + (*EgressResponse)(nil), // 1: livekit.EgressResponse + (*IngressRequest)(nil), // 2: livekit.IngressRequest + (*IngressResponse)(nil), // 3: livekit.IngressResponse + (*UpdateStreamRequest)(nil), // 4: livekit.UpdateStreamRequest + (*StopEgressRequest)(nil), // 5: livekit.StopEgressRequest + (*EgressInfo)(nil), // 6: livekit.EgressInfo + (*UpdateIngressRequest)(nil), // 7: livekit.UpdateIngressRequest + (*DeleteIngressRequest)(nil), // 8: livekit.DeleteIngressRequest + (*IngressState)(nil), // 9: livekit.IngressState } var file_livekit_rpc_internal_proto_depIdxs = []int32{ - 8, // 0: livekit.StartEgressRequest.room_composite:type_name -> livekit.RoomCompositeEgressRequest - 9, // 1: livekit.StartEgressRequest.track_composite:type_name -> livekit.TrackCompositeEgressRequest - 10, // 2: livekit.StartEgressRequest.track:type_name -> livekit.TrackEgressRequest - 11, // 3: livekit.StartEgressRequest.web:type_name -> livekit.WebEgressRequest - 12, // 4: livekit.EgressRequest.update_stream:type_name -> livekit.UpdateStreamRequest - 13, // 5: livekit.EgressRequest.stop:type_name -> livekit.StopEgressRequest - 14, // 6: livekit.EgressResponse.info:type_name -> livekit.EgressInfo - 15, // 7: livekit.IngressRequest.update:type_name -> livekit.UpdateIngressRequest - 16, // 8: livekit.IngressRequest.delete:type_name -> livekit.DeleteIngressRequest - 17, // 9: livekit.UpdateIngressStateRequest.state:type_name -> livekit.IngressState - 17, // 10: livekit.IngressResponse.state:type_name -> livekit.IngressState - 18, // 11: livekit.GetIngressInfoResponse.info:type_name -> livekit.IngressInfo - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 4, // 0: livekit.EgressRequest.update_stream:type_name -> livekit.UpdateStreamRequest + 5, // 1: livekit.EgressRequest.stop:type_name -> livekit.StopEgressRequest + 6, // 2: livekit.EgressResponse.info:type_name -> livekit.EgressInfo + 7, // 3: livekit.IngressRequest.update:type_name -> livekit.UpdateIngressRequest + 8, // 4: livekit.IngressRequest.delete:type_name -> livekit.DeleteIngressRequest + 9, // 5: livekit.IngressResponse.state:type_name -> livekit.IngressState + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_livekit_rpc_internal_proto_init() } @@ -925,18 +474,6 @@ func file_livekit_rpc_internal_proto_init() { file_livekit_ingress_proto_init() if !protoimpl.UnsafeEnabled { file_livekit_rpc_internal_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartEgressRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_livekit_rpc_internal_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EgressRequest); i { case 0: return &v.state @@ -948,7 +485,7 @@ func file_livekit_rpc_internal_proto_init() { return nil } } - file_livekit_rpc_internal_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_livekit_rpc_internal_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EgressResponse); i { case 0: return &v.state @@ -960,7 +497,7 @@ func file_livekit_rpc_internal_proto_init() { return nil } } - file_livekit_rpc_internal_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_livekit_rpc_internal_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IngressRequest); i { case 0: return &v.state @@ -972,31 +509,7 @@ func file_livekit_rpc_internal_proto_init() { return nil } } - file_livekit_rpc_internal_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetIngressInfoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_livekit_rpc_internal_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateIngressStateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_livekit_rpc_internal_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_livekit_rpc_internal_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IngressResponse); i { case 0: return &v.state @@ -1008,30 +521,12 @@ func file_livekit_rpc_internal_proto_init() { return nil } } - file_livekit_rpc_internal_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetIngressInfoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } file_livekit_rpc_internal_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*StartEgressRequest_RoomComposite)(nil), - (*StartEgressRequest_TrackComposite)(nil), - (*StartEgressRequest_Track)(nil), - (*StartEgressRequest_Web)(nil), - } - file_livekit_rpc_internal_proto_msgTypes[1].OneofWrappers = []interface{}{ (*EgressRequest_UpdateStream)(nil), (*EgressRequest_Stop)(nil), } - file_livekit_rpc_internal_proto_msgTypes[3].OneofWrappers = []interface{}{ + file_livekit_rpc_internal_proto_msgTypes[2].OneofWrappers = []interface{}{ (*IngressRequest_Update)(nil), (*IngressRequest_Delete)(nil), } @@ -1041,7 +536,7 @@ func file_livekit_rpc_internal_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_livekit_rpc_internal_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/livekit_rpc_internal.proto b/livekit_rpc_internal.proto index aa3324b4..9e7ed06e 100644 --- a/livekit_rpc_internal.proto +++ b/livekit_rpc_internal.proto @@ -8,28 +8,9 @@ option ruby_package = "LiveKit::Proto"; import "livekit_egress.proto"; import "livekit_ingress.proto"; -message StartEgressRequest { - // request metadata - string egress_id = 1; - string request_id = 2; - string sender_id = 10; - int64 sent_at = 4; - - // request - oneof request { - RoomCompositeEgressRequest room_composite = 5; - TrackCompositeEgressRequest track_composite = 6; - TrackEgressRequest track = 7; - WebEgressRequest web = 11; - } - - // connection info - string room_id = 3; - string token = 8; - string ws_url = 9; -} - message EgressRequest { + option deprecated = true; + // request metadata string egress_id = 1; string request_id = 2; @@ -43,6 +24,8 @@ message EgressRequest { } message EgressResponse { + option deprecated = true; + EgressInfo info = 1; string error = 2; string request_id = 3; @@ -50,6 +33,8 @@ message EgressResponse { // service -> ingress notification of a change in the ingress configuration message IngressRequest { + option deprecated = true; + // request metadata string ingress_id = 1; string request_id = 2; @@ -61,31 +46,10 @@ message IngressRequest { } } -// Query an ingress info from an ingress ID or stream key -message GetIngressInfoRequest { - string ingress_id = 1; - string stream_key = 2; - string request_id = 3; - string sender_id = 4; - int64 sent_at = 5; -} - -// Request to store an update to the ingress state ingress -> service -message UpdateIngressStateRequest { - string ingress_id = 1; - IngressState state = 2; -} - message IngressResponse { + option deprecated = true; + IngressState state = 1; string error = 2; string request_id = 3; } - -message GetIngressInfoResponse { - IngressInfo info = 1; - string token = 2; - string ws_url = 3; - string error = 4; - string request_id = 5; -} diff --git a/magefile.go b/magefile.go index a3fa94f2..6a762891 100644 --- a/magefile.go +++ b/magefile.go @@ -9,6 +9,8 @@ import ( "os" "os/exec" "path/filepath" + + "github.com/livekit/mageutil" ) var Default = Proto @@ -28,6 +30,11 @@ func Proto() error { "livekit_rtc.proto", "livekit_webhook.proto", } + psrpcProtoFiles := []string{ + "rpc/egress.proto", + "rpc/ingress.proto", + "rpc/io.proto", + } fmt.Println("generating protobuf") target := "livekit" @@ -81,6 +88,34 @@ func Proto() error { if err := cmd.Run(); err != nil { return err } + + fmt.Println("generating psrpc protobuf") + + psrpcDir, err := mageutil.GetPkgDir("github.com/livekit/psrpc") + if err != nil { + return err + } + psrpcPath, err := mageutil.GetToolPath("protoc-gen-psrpc") + if err != nil { + return err + } + + args = append([]string{ + "--go_out", ".", + "--psrpc_out", ".", + "--go_opt=paths=source_relative", + "--psrpc_opt=paths=source_relative", + "--plugin=go=" + protocGoPath, + "--plugin=psrpc=" + psrpcPath, + "-I" + psrpcDir + "/protoc-gen-psrpc/options", + "-I=.", + }, psrpcProtoFiles...) + cmd = exec.Command(protoc, args...) + mageutil.ConnectStd(cmd) + if err = cmd.Run(); err != nil { + return err + } + return nil } diff --git a/renovate.json b/renovate.json index 9e3613eb..41fd3213 100644 --- a/renovate.json +++ b/renovate.json @@ -3,29 +3,18 @@ "extends": [ "config:base" ], - "postUpdateOptions": [ - "gomodTidy" - ], "commitBody": "Generated by renovateBot", "packageRules": [ { - "matchUpdateTypes": [ - "minor", - "patch", - "pin", - "digest" - ], - "automerge": false + "matchManagers": ["github-actions"], + "groupName": "github workflows" }, { - "packagePatterns": [ - "^golang.org/x/" - ], - "schedule": [ - "on the first day of the month" - ] + "matchManagers": ["gomod"], + "groupName": "go deps" } ], - "ignorePaths": [ + "postUpdateOptions": [ + "gomodTidy" ] } diff --git a/rpc/egress.pb.go b/rpc/egress.pb.go new file mode 100644 index 00000000..4090d8fe --- /dev/null +++ b/rpc/egress.pb.go @@ -0,0 +1,467 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: rpc/egress.proto + +package rpc + +import ( + livekit "github.com/livekit/protocol/livekit" + _ "github.com/livekit/psrpc/protoc-gen-psrpc/options" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type StartEgressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // request metadata + EgressId string `protobuf:"bytes,1,opt,name=egress_id,json=egressId,proto3" json:"egress_id,omitempty"` + // Deprecated: Do not use. + RequestId string `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // Deprecated: Do not use. + SenderId string `protobuf:"bytes,10,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` + // Deprecated: Do not use. + SentAt int64 `protobuf:"varint,4,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` + // request + // + // Types that are assignable to Request: + // + // *StartEgressRequest_RoomComposite + // *StartEgressRequest_TrackComposite + // *StartEgressRequest_Track + // *StartEgressRequest_Web + Request isStartEgressRequest_Request `protobuf_oneof:"request"` + // connection info + RoomId string `protobuf:"bytes,3,opt,name=room_id,json=roomId,proto3" json:"room_id,omitempty"` + Token string `protobuf:"bytes,8,opt,name=token,proto3" json:"token,omitempty"` + WsUrl string `protobuf:"bytes,9,opt,name=ws_url,json=wsUrl,proto3" json:"ws_url,omitempty"` +} + +func (x *StartEgressRequest) Reset() { + *x = StartEgressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_egress_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartEgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartEgressRequest) ProtoMessage() {} + +func (x *StartEgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_egress_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartEgressRequest.ProtoReflect.Descriptor instead. +func (*StartEgressRequest) Descriptor() ([]byte, []int) { + return file_rpc_egress_proto_rawDescGZIP(), []int{0} +} + +func (x *StartEgressRequest) GetEgressId() string { + if x != nil { + return x.EgressId + } + return "" +} + +// Deprecated: Do not use. +func (x *StartEgressRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +// Deprecated: Do not use. +func (x *StartEgressRequest) GetSenderId() string { + if x != nil { + return x.SenderId + } + return "" +} + +// Deprecated: Do not use. +func (x *StartEgressRequest) GetSentAt() int64 { + if x != nil { + return x.SentAt + } + return 0 +} + +func (m *StartEgressRequest) GetRequest() isStartEgressRequest_Request { + if m != nil { + return m.Request + } + return nil +} + +func (x *StartEgressRequest) GetRoomComposite() *livekit.RoomCompositeEgressRequest { + if x, ok := x.GetRequest().(*StartEgressRequest_RoomComposite); ok { + return x.RoomComposite + } + return nil +} + +func (x *StartEgressRequest) GetTrackComposite() *livekit.TrackCompositeEgressRequest { + if x, ok := x.GetRequest().(*StartEgressRequest_TrackComposite); ok { + return x.TrackComposite + } + return nil +} + +func (x *StartEgressRequest) GetTrack() *livekit.TrackEgressRequest { + if x, ok := x.GetRequest().(*StartEgressRequest_Track); ok { + return x.Track + } + return nil +} + +func (x *StartEgressRequest) GetWeb() *livekit.WebEgressRequest { + if x, ok := x.GetRequest().(*StartEgressRequest_Web); ok { + return x.Web + } + return nil +} + +func (x *StartEgressRequest) GetRoomId() string { + if x != nil { + return x.RoomId + } + return "" +} + +func (x *StartEgressRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *StartEgressRequest) GetWsUrl() string { + if x != nil { + return x.WsUrl + } + return "" +} + +type isStartEgressRequest_Request interface { + isStartEgressRequest_Request() +} + +type StartEgressRequest_RoomComposite struct { + RoomComposite *livekit.RoomCompositeEgressRequest `protobuf:"bytes,5,opt,name=room_composite,json=roomComposite,proto3,oneof"` +} + +type StartEgressRequest_TrackComposite struct { + TrackComposite *livekit.TrackCompositeEgressRequest `protobuf:"bytes,6,opt,name=track_composite,json=trackComposite,proto3,oneof"` +} + +type StartEgressRequest_Track struct { + Track *livekit.TrackEgressRequest `protobuf:"bytes,7,opt,name=track,proto3,oneof"` +} + +type StartEgressRequest_Web struct { + Web *livekit.WebEgressRequest `protobuf:"bytes,11,opt,name=web,proto3,oneof"` +} + +func (*StartEgressRequest_RoomComposite) isStartEgressRequest_Request() {} + +func (*StartEgressRequest_TrackComposite) isStartEgressRequest_Request() {} + +func (*StartEgressRequest_Track) isStartEgressRequest_Request() {} + +func (*StartEgressRequest_Web) isStartEgressRequest_Request() {} + +type ListActiveEgressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListActiveEgressRequest) Reset() { + *x = ListActiveEgressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_egress_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListActiveEgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActiveEgressRequest) ProtoMessage() {} + +func (x *ListActiveEgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_egress_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActiveEgressRequest.ProtoReflect.Descriptor instead. +func (*ListActiveEgressRequest) Descriptor() ([]byte, []int) { + return file_rpc_egress_proto_rawDescGZIP(), []int{1} +} + +type ListActiveEgressResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EgressIds []string `protobuf:"bytes,1,rep,name=egress_ids,json=egressIds,proto3" json:"egress_ids,omitempty"` +} + +func (x *ListActiveEgressResponse) Reset() { + *x = ListActiveEgressResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_egress_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListActiveEgressResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActiveEgressResponse) ProtoMessage() {} + +func (x *ListActiveEgressResponse) ProtoReflect() protoreflect.Message { + mi := &file_rpc_egress_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActiveEgressResponse.ProtoReflect.Descriptor instead. +func (*ListActiveEgressResponse) Descriptor() ([]byte, []int) { + return file_rpc_egress_proto_rawDescGZIP(), []int{2} +} + +func (x *ListActiveEgressResponse) GetEgressIds() []string { + if x != nil { + return x.EgressIds + } + return nil +} + +var File_rpc_egress_proto protoreflect.FileDescriptor + +var file_rpc_egress_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x03, 0x72, 0x70, 0x63, 0x1a, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x5f, + 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x03, 0x0a, + 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, + 0x74, 0x12, 0x4c, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6c, 0x69, 0x76, 0x65, + 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x0d, 0x72, 0x6f, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x12, + 0x4f, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, + 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, + 0x12, 0x33, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x45, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x03, 0x77, 0x65, 0x62, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x57, 0x65, 0x62, + 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, + 0x03, 0x77, 0x65, 0x62, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x77, 0x73, 0x55, 0x72, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x39, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x45, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x73, 0x32, 0xb4, 0x01, 0x0a, 0x0e, + 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x49, + 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x17, 0x2e, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, + 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x0c, 0xb2, 0x89, 0x01, + 0x02, 0x20, 0x01, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x2e, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x45, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x70, + 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x45, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xb2, 0x89, 0x01, 0x02, + 0x08, 0x01, 0x32, 0xa1, 0x01, 0x0a, 0x0d, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x45, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x06, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0x12, + 0x45, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x2e, + 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x69, 0x76, 0x65, + 0x6b, 0x69, 0x74, 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x06, + 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, + 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_rpc_egress_proto_rawDescOnce sync.Once + file_rpc_egress_proto_rawDescData = file_rpc_egress_proto_rawDesc +) + +func file_rpc_egress_proto_rawDescGZIP() []byte { + file_rpc_egress_proto_rawDescOnce.Do(func() { + file_rpc_egress_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_egress_proto_rawDescData) + }) + return file_rpc_egress_proto_rawDescData +} + +var file_rpc_egress_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_rpc_egress_proto_goTypes = []interface{}{ + (*StartEgressRequest)(nil), // 0: rpc.StartEgressRequest + (*ListActiveEgressRequest)(nil), // 1: rpc.ListActiveEgressRequest + (*ListActiveEgressResponse)(nil), // 2: rpc.ListActiveEgressResponse + (*livekit.RoomCompositeEgressRequest)(nil), // 3: livekit.RoomCompositeEgressRequest + (*livekit.TrackCompositeEgressRequest)(nil), // 4: livekit.TrackCompositeEgressRequest + (*livekit.TrackEgressRequest)(nil), // 5: livekit.TrackEgressRequest + (*livekit.WebEgressRequest)(nil), // 6: livekit.WebEgressRequest + (*livekit.UpdateStreamRequest)(nil), // 7: livekit.UpdateStreamRequest + (*livekit.StopEgressRequest)(nil), // 8: livekit.StopEgressRequest + (*livekit.EgressInfo)(nil), // 9: livekit.EgressInfo +} +var file_rpc_egress_proto_depIdxs = []int32{ + 3, // 0: rpc.StartEgressRequest.room_composite:type_name -> livekit.RoomCompositeEgressRequest + 4, // 1: rpc.StartEgressRequest.track_composite:type_name -> livekit.TrackCompositeEgressRequest + 5, // 2: rpc.StartEgressRequest.track:type_name -> livekit.TrackEgressRequest + 6, // 3: rpc.StartEgressRequest.web:type_name -> livekit.WebEgressRequest + 0, // 4: rpc.EgressInternal.StartEgress:input_type -> rpc.StartEgressRequest + 1, // 5: rpc.EgressInternal.ListActiveEgress:input_type -> rpc.ListActiveEgressRequest + 7, // 6: rpc.EgressHandler.UpdateStream:input_type -> livekit.UpdateStreamRequest + 8, // 7: rpc.EgressHandler.StopEgress:input_type -> livekit.StopEgressRequest + 9, // 8: rpc.EgressInternal.StartEgress:output_type -> livekit.EgressInfo + 2, // 9: rpc.EgressInternal.ListActiveEgress:output_type -> rpc.ListActiveEgressResponse + 9, // 10: rpc.EgressHandler.UpdateStream:output_type -> livekit.EgressInfo + 9, // 11: rpc.EgressHandler.StopEgress:output_type -> livekit.EgressInfo + 8, // [8:12] is the sub-list for method output_type + 4, // [4:8] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_rpc_egress_proto_init() } +func file_rpc_egress_proto_init() { + if File_rpc_egress_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_egress_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartEgressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_egress_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListActiveEgressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_egress_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListActiveEgressResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_rpc_egress_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*StartEgressRequest_RoomComposite)(nil), + (*StartEgressRequest_TrackComposite)(nil), + (*StartEgressRequest_Track)(nil), + (*StartEgressRequest_Web)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_egress_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_rpc_egress_proto_goTypes, + DependencyIndexes: file_rpc_egress_proto_depIdxs, + MessageInfos: file_rpc_egress_proto_msgTypes, + }.Build() + File_rpc_egress_proto = out.File + file_rpc_egress_proto_rawDesc = nil + file_rpc_egress_proto_goTypes = nil + file_rpc_egress_proto_depIdxs = nil +} diff --git a/rpc/egress.proto b/rpc/egress.proto new file mode 100644 index 00000000..68ebad50 --- /dev/null +++ b/rpc/egress.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; + +package rpc; + +option go_package = "github.com/livekit/livekit/pkg/service/rpc"; + +import "options.proto"; +import "livekit_egress.proto"; + +service EgressInternal { + rpc StartEgress(StartEgressRequest) returns (livekit.EgressInfo) { + option (psrpc.options).affinity_func = true; + option (psrpc.options).topics = true; + }; + rpc ListActiveEgress(ListActiveEgressRequest) returns (ListActiveEgressResponse) { + option (psrpc.options).multi = true; + } +} + +service EgressHandler { + rpc UpdateStream(livekit.UpdateStreamRequest) returns (livekit.EgressInfo) { + option (psrpc.options).topics = true; + } + rpc StopEgress(livekit.StopEgressRequest) returns (livekit.EgressInfo) { + option (psrpc.options).topics = true; + } +} + +message StartEgressRequest { + // request metadata + string egress_id = 1; + string request_id = 2 [deprecated = true]; + string sender_id = 10 [deprecated = true]; + int64 sent_at = 4 [deprecated = true]; + + // request + oneof request { + livekit.RoomCompositeEgressRequest room_composite = 5; + livekit.TrackCompositeEgressRequest track_composite = 6; + livekit.TrackEgressRequest track = 7; + livekit.WebEgressRequest web = 11; + } + + // connection info + string room_id = 3; + string token = 8; + string ws_url = 9; +} + +message ListActiveEgressRequest {} + +message ListActiveEgressResponse { + repeated string egress_ids = 1; +} diff --git a/rpc/egress.psrpc.go b/rpc/egress.psrpc.go new file mode 100644 index 00000000..a2bc21e7 --- /dev/null +++ b/rpc/egress.psrpc.go @@ -0,0 +1,265 @@ +// Code generated by protoc-gen-psrpc v0.2.5, DO NOT EDIT. +// source: rpc/egress.proto + +package rpc + +import context "context" +import psrpc "github.com/livekit/psrpc" +import version "github.com/livekit/psrpc/version" +import livekit "github.com/livekit/protocol/livekit" + +var _ = version.PsrpcVersion_0_2_5 + +// =============================== +// EgressInternal Client Interface +// =============================== + +type EgressInternalClient interface { + StartEgress(context.Context, string, *StartEgressRequest, ...psrpc.RequestOption) (*livekit.EgressInfo, error) + + ListActiveEgress(context.Context, *ListActiveEgressRequest, ...psrpc.RequestOption) (<-chan *psrpc.Response[*ListActiveEgressResponse], error) +} + +// =================================== +// EgressInternal ServerImpl Interface +// =================================== + +type EgressInternalServerImpl interface { + StartEgress(context.Context, *StartEgressRequest) (*livekit.EgressInfo, error) + StartEgressAffinity(*StartEgressRequest) float32 + + ListActiveEgress(context.Context, *ListActiveEgressRequest) (*ListActiveEgressResponse, error) +} + +// =============================== +// EgressInternal Server Interface +// =============================== + +type EgressInternalServer interface { + RegisterStartEgressTopic(string) error + DeregisterStartEgressTopic(string) + + // Close and wait for pending RPCs to complete + Shutdown() + + // Close immediately, without waiting for pending RPCs + Kill() +} + +// ===================== +// EgressInternal Client +// ===================== + +type egressInternalClient struct { + client *psrpc.RPCClient +} + +// NewEgressInternalClient creates a psrpc client that implements the EgressInternalClient interface. +func NewEgressInternalClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (EgressInternalClient, error) { + rpcClient, err := psrpc.NewRPCClient("EgressInternal", clientID, bus, opts...) + if err != nil { + return nil, err + } + + return &egressInternalClient{ + client: rpcClient, + }, nil +} + +func (c *egressInternalClient) StartEgress(ctx context.Context, topic string, req *StartEgressRequest, opts ...psrpc.RequestOption) (*livekit.EgressInfo, error) { + return psrpc.RequestSingle[*livekit.EgressInfo](ctx, c.client, "StartEgress", topic, req, opts...) +} + +func (c *egressInternalClient) ListActiveEgress(ctx context.Context, req *ListActiveEgressRequest, opts ...psrpc.RequestOption) (<-chan *psrpc.Response[*ListActiveEgressResponse], error) { + return psrpc.RequestMulti[*ListActiveEgressResponse](ctx, c.client, "ListActiveEgress", "", req, opts...) +} + +// ===================== +// EgressInternal Server +// ===================== + +type egressInternalServer struct { + svc EgressInternalServerImpl + rpc *psrpc.RPCServer +} + +// NewEgressInternalServer builds a RPCServer that will route requests +// to the corresponding method in the provided svc implementation. +func NewEgressInternalServer(serverID string, svc EgressInternalServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (EgressInternalServer, error) { + s := psrpc.NewRPCServer("EgressInternal", serverID, bus, opts...) + + var err error + err = psrpc.RegisterHandler(s, "ListActiveEgress", "", svc.ListActiveEgress, nil) + if err != nil { + s.Close(false) + return nil, err + } + + return &egressInternalServer{ + svc: svc, + rpc: s, + }, nil +} + +func (s *egressInternalServer) RegisterStartEgressTopic(topic string) error { + return psrpc.RegisterHandler(s.rpc, "StartEgress", topic, s.svc.StartEgress, s.svc.StartEgressAffinity) +} + +func (s *egressInternalServer) DeregisterStartEgressTopic(topic string) { + s.rpc.DeregisterHandler("StartEgress", topic) +} + +func (s *egressInternalServer) Shutdown() { + s.rpc.Close(false) +} + +func (s *egressInternalServer) Kill() { + s.rpc.Close(true) +} + +// ============================== +// EgressHandler Client Interface +// ============================== + +type EgressHandlerClient interface { + UpdateStream(context.Context, string, *livekit.UpdateStreamRequest, ...psrpc.RequestOption) (*livekit.EgressInfo, error) + + StopEgress(context.Context, string, *livekit.StopEgressRequest, ...psrpc.RequestOption) (*livekit.EgressInfo, error) +} + +// ================================== +// EgressHandler ServerImpl Interface +// ================================== + +type EgressHandlerServerImpl interface { + UpdateStream(context.Context, *livekit.UpdateStreamRequest) (*livekit.EgressInfo, error) + + StopEgress(context.Context, *livekit.StopEgressRequest) (*livekit.EgressInfo, error) +} + +// ============================== +// EgressHandler Server Interface +// ============================== + +type EgressHandlerServer interface { + RegisterUpdateStreamTopic(string) error + DeregisterUpdateStreamTopic(string) + + RegisterStopEgressTopic(string) error + DeregisterStopEgressTopic(string) + + // Close and wait for pending RPCs to complete + Shutdown() + + // Close immediately, without waiting for pending RPCs + Kill() +} + +// ==================== +// EgressHandler Client +// ==================== + +type egressHandlerClient struct { + client *psrpc.RPCClient +} + +// NewEgressHandlerClient creates a psrpc client that implements the EgressHandlerClient interface. +func NewEgressHandlerClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (EgressHandlerClient, error) { + rpcClient, err := psrpc.NewRPCClient("EgressHandler", clientID, bus, opts...) + if err != nil { + return nil, err + } + + return &egressHandlerClient{ + client: rpcClient, + }, nil +} + +func (c *egressHandlerClient) UpdateStream(ctx context.Context, topic string, req *livekit.UpdateStreamRequest, opts ...psrpc.RequestOption) (*livekit.EgressInfo, error) { + return psrpc.RequestSingle[*livekit.EgressInfo](ctx, c.client, "UpdateStream", topic, req, opts...) +} + +func (c *egressHandlerClient) StopEgress(ctx context.Context, topic string, req *livekit.StopEgressRequest, opts ...psrpc.RequestOption) (*livekit.EgressInfo, error) { + return psrpc.RequestSingle[*livekit.EgressInfo](ctx, c.client, "StopEgress", topic, req, opts...) +} + +// ==================== +// EgressHandler Server +// ==================== + +type egressHandlerServer struct { + svc EgressHandlerServerImpl + rpc *psrpc.RPCServer +} + +// NewEgressHandlerServer builds a RPCServer that will route requests +// to the corresponding method in the provided svc implementation. +func NewEgressHandlerServer(serverID string, svc EgressHandlerServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (EgressHandlerServer, error) { + s := psrpc.NewRPCServer("EgressHandler", serverID, bus, opts...) + + return &egressHandlerServer{ + svc: svc, + rpc: s, + }, nil +} + +func (s *egressHandlerServer) RegisterUpdateStreamTopic(topic string) error { + return psrpc.RegisterHandler(s.rpc, "UpdateStream", topic, s.svc.UpdateStream, nil) +} + +func (s *egressHandlerServer) DeregisterUpdateStreamTopic(topic string) { + s.rpc.DeregisterHandler("UpdateStream", topic) +} + +func (s *egressHandlerServer) RegisterStopEgressTopic(topic string) error { + return psrpc.RegisterHandler(s.rpc, "StopEgress", topic, s.svc.StopEgress, nil) +} + +func (s *egressHandlerServer) DeregisterStopEgressTopic(topic string) { + s.rpc.DeregisterHandler("StopEgress", topic) +} + +func (s *egressHandlerServer) Shutdown() { + s.rpc.Close(false) +} + +func (s *egressHandlerServer) Kill() { + s.rpc.Close(true) +} + +var psrpcFileDescriptor0 = []byte{ + // 520 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xd1, 0x6e, 0xda, 0x4c, + 0x10, 0x85, 0xff, 0xc5, 0xc1, 0xe0, 0xe1, 0x87, 0x46, 0xd3, 0x54, 0x6c, 0x20, 0x51, 0x29, 0xed, + 0x05, 0xaa, 0x5a, 0x23, 0x91, 0xab, 0x5e, 0x86, 0x0a, 0x29, 0x96, 0x22, 0x55, 0x32, 0x8d, 0x22, + 0xf5, 0x06, 0x19, 0x7b, 0x4b, 0x2d, 0xc0, 0xbb, 0xdd, 0x5d, 0xe0, 0x19, 0xf2, 0x18, 0x7d, 0x83, + 0x2a, 0x0f, 0xd5, 0xe7, 0xa8, 0xbc, 0x36, 0x2e, 0x10, 0x51, 0xf5, 0x0a, 0xed, 0x77, 0xce, 0x1c, + 0xcd, 0x0c, 0x63, 0x38, 0x95, 0x22, 0xec, 0xb3, 0x99, 0x64, 0x4a, 0xb9, 0x42, 0x72, 0xcd, 0xd1, + 0x92, 0x22, 0x6c, 0xd5, 0xb9, 0xd0, 0x31, 0x4f, 0x72, 0xd6, 0x3a, 0x5b, 0xc4, 0x6b, 0x36, 0x8f, + 0xf5, 0x64, 0xd7, 0xd9, 0xfd, 0x65, 0x01, 0x8e, 0x75, 0x20, 0xf5, 0xc8, 0x50, 0x9f, 0x7d, 0x5f, + 0x31, 0xa5, 0xb1, 0x0d, 0x4e, 0x66, 0x9b, 0xc4, 0x11, 0x25, 0x1d, 0xd2, 0x73, 0xfc, 0x6a, 0x06, + 0xbc, 0x08, 0x5f, 0x01, 0xc8, 0xcc, 0x97, 0xaa, 0xa5, 0x54, 0x1d, 0x96, 0x28, 0xf1, 0x9d, 0x9c, + 0x7a, 0x11, 0xbe, 0x04, 0x47, 0xb1, 0x24, 0x62, 0x32, 0x75, 0x40, 0xe1, 0xa8, 0x66, 0xd0, 0x8b, + 0xb0, 0x0d, 0x15, 0xc5, 0x12, 0x3d, 0x09, 0x34, 0x3d, 0xe9, 0x90, 0x9e, 0x65, 0x64, 0x3b, 0x45, + 0xd7, 0x1a, 0x6f, 0xa1, 0x21, 0x39, 0x5f, 0x4e, 0x42, 0xbe, 0x14, 0x5c, 0xc5, 0x9a, 0xd1, 0x72, + 0x87, 0xf4, 0x6a, 0x83, 0xd7, 0x6e, 0x3e, 0x83, 0xeb, 0x73, 0xbe, 0xfc, 0xb8, 0x55, 0xf7, 0x5a, + 0xbf, 0xf9, 0xcf, 0xaf, 0xcb, 0x5d, 0x15, 0x3f, 0xc1, 0x33, 0x2d, 0x83, 0x70, 0xbe, 0x13, 0x67, + 0x9b, 0xb8, 0x37, 0x45, 0xdc, 0xe7, 0x54, 0x3f, 0x9a, 0xd7, 0xd0, 0x7b, 0x32, 0x5e, 0x41, 0xd9, + 0x10, 0x5a, 0x31, 0x31, 0xed, 0xfd, 0x98, 0xc3, 0xea, 0xcc, 0x8b, 0xef, 0xc1, 0xda, 0xb0, 0x29, + 0xad, 0x99, 0x92, 0xf3, 0xa2, 0xe4, 0x9e, 0x4d, 0x0f, 0x0b, 0x52, 0x1f, 0x36, 0xa1, 0x62, 0x56, + 0x10, 0x47, 0xd4, 0x32, 0xeb, 0xb7, 0xd3, 0xa7, 0x17, 0xe1, 0x19, 0x94, 0x35, 0x9f, 0xb3, 0x84, + 0x56, 0x0d, 0xce, 0x1e, 0xf8, 0x02, 0xec, 0x8d, 0x9a, 0xac, 0xe4, 0x82, 0x3a, 0x19, 0xde, 0xa8, + 0x3b, 0xb9, 0x18, 0x3a, 0x50, 0xc9, 0xff, 0x93, 0xee, 0x39, 0x34, 0x6f, 0x63, 0xa5, 0xaf, 0x43, + 0x1d, 0xaf, 0xf7, 0x27, 0xec, 0x7e, 0x00, 0xfa, 0x54, 0x52, 0x82, 0x27, 0x8a, 0xe1, 0x25, 0x40, + 0x71, 0x08, 0x8a, 0x92, 0x8e, 0xd5, 0x73, 0x7c, 0x67, 0x7b, 0x09, 0x6a, 0xf0, 0x93, 0x40, 0x23, + 0xab, 0xf0, 0x12, 0xcd, 0x64, 0x12, 0x2c, 0x70, 0x04, 0xb5, 0x9d, 0x83, 0xc2, 0xa6, 0x2b, 0x45, + 0xe8, 0x3e, 0x3d, 0xb1, 0xd6, 0xf3, 0x62, 0x07, 0xdb, 0x80, 0xaf, 0xbc, 0x5b, 0x7d, 0x7c, 0x20, + 0x27, 0xe9, 0xc1, 0xe1, 0x3d, 0x9c, 0x1e, 0x36, 0x85, 0x17, 0x26, 0xeb, 0xc8, 0x18, 0xad, 0xcb, + 0x23, 0x6a, 0x36, 0x49, 0xd7, 0x7e, 0x7c, 0x20, 0xa5, 0x2a, 0x19, 0xfc, 0x20, 0x50, 0xcf, 0xa4, + 0x9b, 0x20, 0x89, 0x16, 0x4c, 0xa2, 0x07, 0xff, 0xdf, 0x89, 0x28, 0xd0, 0x6c, 0xac, 0x25, 0x0b, + 0x96, 0x78, 0x51, 0x74, 0xb6, 0x8b, 0xff, 0xda, 0xb7, 0x09, 0xa7, 0x04, 0x47, 0x00, 0x63, 0xcd, + 0x45, 0xde, 0x6f, 0xab, 0xb0, 0xfe, 0x81, 0xff, 0x12, 0x33, 0x7c, 0xf7, 0xe5, 0xed, 0x2c, 0xd6, + 0xdf, 0x56, 0x53, 0x37, 0xe4, 0xcb, 0x7e, 0x6e, 0x2c, 0x7e, 0xc5, 0x7c, 0xd6, 0x57, 0x4c, 0xae, + 0xe3, 0x90, 0xf5, 0xa5, 0x08, 0xa7, 0xb6, 0xf9, 0x94, 0xaf, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x20, 0xd1, 0xe8, 0x08, 0x08, 0x04, 0x00, 0x00, +} diff --git a/rpc/egress_client.go b/rpc/egress_client.go new file mode 100644 index 00000000..eba43b4c --- /dev/null +++ b/rpc/egress_client.go @@ -0,0 +1,36 @@ +package rpc + +import ( + "github.com/livekit/protocol/livekit" + "github.com/livekit/psrpc" +) + +type EgressClient interface { + EgressInternalClient + EgressHandlerClient +} + +type egressClient struct { + EgressInternalClient + EgressHandlerClient +} + +func NewEgressClient(nodeID livekit.NodeID, bus psrpc.MessageBus) (EgressClient, error) { + if bus == nil { + return nil, nil + } + + clientID := string(nodeID) + internalClient, err := NewEgressInternalClient(clientID, bus) + if err != nil { + return nil, err + } + handlerClient, err := NewEgressHandlerClient(clientID, bus) + if err != nil { + return nil, err + } + return &egressClient{ + EgressInternalClient: internalClient, + EgressHandlerClient: handlerClient, + }, nil +} diff --git a/rpc/ingress.pb.go b/rpc/ingress.pb.go new file mode 100644 index 00000000..470cba4f --- /dev/null +++ b/rpc/ingress.pb.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: rpc/ingress.proto + +package rpc + +import ( + livekit "github.com/livekit/protocol/livekit" + _ "github.com/livekit/psrpc/protoc-gen-psrpc/options" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListActiveIngressRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListActiveIngressRequest) Reset() { + *x = ListActiveIngressRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_ingress_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListActiveIngressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActiveIngressRequest) ProtoMessage() {} + +func (x *ListActiveIngressRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_ingress_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActiveIngressRequest.ProtoReflect.Descriptor instead. +func (*ListActiveIngressRequest) Descriptor() ([]byte, []int) { + return file_rpc_ingress_proto_rawDescGZIP(), []int{0} +} + +type ListActiveIngressResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IngressIds []string `protobuf:"bytes,1,rep,name=ingress_ids,json=ingressIds,proto3" json:"ingress_ids,omitempty"` +} + +func (x *ListActiveIngressResponse) Reset() { + *x = ListActiveIngressResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_ingress_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListActiveIngressResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListActiveIngressResponse) ProtoMessage() {} + +func (x *ListActiveIngressResponse) ProtoReflect() protoreflect.Message { + mi := &file_rpc_ingress_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListActiveIngressResponse.ProtoReflect.Descriptor instead. +func (*ListActiveIngressResponse) Descriptor() ([]byte, []int) { + return file_rpc_ingress_proto_rawDescGZIP(), []int{1} +} + +func (x *ListActiveIngressResponse) GetIngressIds() []string { + if x != nil { + return x.IngressIds + } + return nil +} + +var File_rpc_ingress_proto protoreflect.FileDescriptor + +var file_rpc_ingress_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x72, 0x70, 0x63, 0x1a, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, + 0x5f, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1a, + 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3c, 0x0a, 0x19, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x73, 0x32, 0x6d, 0x0a, 0x0f, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x11, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x1d, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x06, 0xb2, 0x89, 0x01, 0x02, 0x08, 0x01, 0x32, 0xae, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0d, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x69, + 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x69, 0x76, + 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x06, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0x12, 0x4d, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x2e, 0x6c, 0x69, 0x76, + 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, + 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x22, 0x06, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, + 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_rpc_ingress_proto_rawDescOnce sync.Once + file_rpc_ingress_proto_rawDescData = file_rpc_ingress_proto_rawDesc +) + +func file_rpc_ingress_proto_rawDescGZIP() []byte { + file_rpc_ingress_proto_rawDescOnce.Do(func() { + file_rpc_ingress_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_ingress_proto_rawDescData) + }) + return file_rpc_ingress_proto_rawDescData +} + +var file_rpc_ingress_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_rpc_ingress_proto_goTypes = []interface{}{ + (*ListActiveIngressRequest)(nil), // 0: rpc.ListActiveIngressRequest + (*ListActiveIngressResponse)(nil), // 1: rpc.ListActiveIngressResponse + (*livekit.UpdateIngressRequest)(nil), // 2: livekit.UpdateIngressRequest + (*livekit.DeleteIngressRequest)(nil), // 3: livekit.DeleteIngressRequest + (*livekit.IngressState)(nil), // 4: livekit.IngressState +} +var file_rpc_ingress_proto_depIdxs = []int32{ + 0, // 0: rpc.IngressInternal.ListActiveIngress:input_type -> rpc.ListActiveIngressRequest + 2, // 1: rpc.IngressHandler.UpdateIngress:input_type -> livekit.UpdateIngressRequest + 3, // 2: rpc.IngressHandler.DeleteIngress:input_type -> livekit.DeleteIngressRequest + 1, // 3: rpc.IngressInternal.ListActiveIngress:output_type -> rpc.ListActiveIngressResponse + 4, // 4: rpc.IngressHandler.UpdateIngress:output_type -> livekit.IngressState + 4, // 5: rpc.IngressHandler.DeleteIngress:output_type -> livekit.IngressState + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_rpc_ingress_proto_init() } +func file_rpc_ingress_proto_init() { + if File_rpc_ingress_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_ingress_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListActiveIngressRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_ingress_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListActiveIngressResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_ingress_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_rpc_ingress_proto_goTypes, + DependencyIndexes: file_rpc_ingress_proto_depIdxs, + MessageInfos: file_rpc_ingress_proto_msgTypes, + }.Build() + File_rpc_ingress_proto = out.File + file_rpc_ingress_proto_rawDesc = nil + file_rpc_ingress_proto_goTypes = nil + file_rpc_ingress_proto_depIdxs = nil +} diff --git a/rpc/ingress.proto b/rpc/ingress.proto new file mode 100644 index 00000000..6648f282 --- /dev/null +++ b/rpc/ingress.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package rpc; + +option go_package = "github.com/livekit/livekit/pkg/service/rpc"; + +import "options.proto"; +import "livekit_ingress.proto"; + +service IngressInternal { + rpc ListActiveIngress(ListActiveIngressRequest) returns (ListActiveIngressResponse) { + option (psrpc.options).multi = true; + }; +} + +service IngressHandler { + rpc UpdateIngress(livekit.UpdateIngressRequest) returns (livekit.IngressState) { + option (psrpc.options).topics = true; + }; + rpc DeleteIngress(livekit.DeleteIngressRequest) returns (livekit.IngressState) { + option (psrpc.options).topics = true; + }; +} + +message ListActiveIngressRequest {} + +message ListActiveIngressResponse { + repeated string ingress_ids = 1; +} diff --git a/rpc/ingress.psrpc.go b/rpc/ingress.psrpc.go new file mode 100644 index 00000000..e22d32bf --- /dev/null +++ b/rpc/ingress.psrpc.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-psrpc v0.2.5, DO NOT EDIT. +// source: rpc/ingress.proto + +package rpc + +import context "context" +import psrpc "github.com/livekit/psrpc" +import version "github.com/livekit/psrpc/version" +import livekit2 "github.com/livekit/protocol/livekit" + +var _ = version.PsrpcVersion_0_2_5 + +// ================================ +// IngressInternal Client Interface +// ================================ + +type IngressInternalClient interface { + ListActiveIngress(context.Context, *ListActiveIngressRequest, ...psrpc.RequestOption) (<-chan *psrpc.Response[*ListActiveIngressResponse], error) +} + +// ==================================== +// IngressInternal ServerImpl Interface +// ==================================== + +type IngressInternalServerImpl interface { + ListActiveIngress(context.Context, *ListActiveIngressRequest) (*ListActiveIngressResponse, error) +} + +// ================================ +// IngressInternal Server Interface +// ================================ + +type IngressInternalServer interface { + // Close and wait for pending RPCs to complete + Shutdown() + + // Close immediately, without waiting for pending RPCs + Kill() +} + +// ====================== +// IngressInternal Client +// ====================== + +type ingressInternalClient struct { + client *psrpc.RPCClient +} + +// NewIngressInternalClient creates a psrpc client that implements the IngressInternalClient interface. +func NewIngressInternalClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (IngressInternalClient, error) { + rpcClient, err := psrpc.NewRPCClient("IngressInternal", clientID, bus, opts...) + if err != nil { + return nil, err + } + + return &ingressInternalClient{ + client: rpcClient, + }, nil +} + +func (c *ingressInternalClient) ListActiveIngress(ctx context.Context, req *ListActiveIngressRequest, opts ...psrpc.RequestOption) (<-chan *psrpc.Response[*ListActiveIngressResponse], error) { + return psrpc.RequestMulti[*ListActiveIngressResponse](ctx, c.client, "ListActiveIngress", "", req, opts...) +} + +// ====================== +// IngressInternal Server +// ====================== + +type ingressInternalServer struct { + svc IngressInternalServerImpl + rpc *psrpc.RPCServer +} + +// NewIngressInternalServer builds a RPCServer that will route requests +// to the corresponding method in the provided svc implementation. +func NewIngressInternalServer(serverID string, svc IngressInternalServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (IngressInternalServer, error) { + s := psrpc.NewRPCServer("IngressInternal", serverID, bus, opts...) + + var err error + err = psrpc.RegisterHandler(s, "ListActiveIngress", "", svc.ListActiveIngress, nil) + if err != nil { + s.Close(false) + return nil, err + } + + return &ingressInternalServer{ + svc: svc, + rpc: s, + }, nil +} + +func (s *ingressInternalServer) Shutdown() { + s.rpc.Close(false) +} + +func (s *ingressInternalServer) Kill() { + s.rpc.Close(true) +} + +// =============================== +// IngressHandler Client Interface +// =============================== + +type IngressHandlerClient interface { + UpdateIngress(context.Context, string, *livekit2.UpdateIngressRequest, ...psrpc.RequestOption) (*livekit2.IngressState, error) + + DeleteIngress(context.Context, string, *livekit2.DeleteIngressRequest, ...psrpc.RequestOption) (*livekit2.IngressState, error) +} + +// =================================== +// IngressHandler ServerImpl Interface +// =================================== + +type IngressHandlerServerImpl interface { + UpdateIngress(context.Context, *livekit2.UpdateIngressRequest) (*livekit2.IngressState, error) + + DeleteIngress(context.Context, *livekit2.DeleteIngressRequest) (*livekit2.IngressState, error) +} + +// =============================== +// IngressHandler Server Interface +// =============================== + +type IngressHandlerServer interface { + RegisterUpdateIngressTopic(string) error + DeregisterUpdateIngressTopic(string) + + RegisterDeleteIngressTopic(string) error + DeregisterDeleteIngressTopic(string) + + // Close and wait for pending RPCs to complete + Shutdown() + + // Close immediately, without waiting for pending RPCs + Kill() +} + +// ===================== +// IngressHandler Client +// ===================== + +type ingressHandlerClient struct { + client *psrpc.RPCClient +} + +// NewIngressHandlerClient creates a psrpc client that implements the IngressHandlerClient interface. +func NewIngressHandlerClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (IngressHandlerClient, error) { + rpcClient, err := psrpc.NewRPCClient("IngressHandler", clientID, bus, opts...) + if err != nil { + return nil, err + } + + return &ingressHandlerClient{ + client: rpcClient, + }, nil +} + +func (c *ingressHandlerClient) UpdateIngress(ctx context.Context, topic string, req *livekit2.UpdateIngressRequest, opts ...psrpc.RequestOption) (*livekit2.IngressState, error) { + return psrpc.RequestSingle[*livekit2.IngressState](ctx, c.client, "UpdateIngress", topic, req, opts...) +} + +func (c *ingressHandlerClient) DeleteIngress(ctx context.Context, topic string, req *livekit2.DeleteIngressRequest, opts ...psrpc.RequestOption) (*livekit2.IngressState, error) { + return psrpc.RequestSingle[*livekit2.IngressState](ctx, c.client, "DeleteIngress", topic, req, opts...) +} + +// ===================== +// IngressHandler Server +// ===================== + +type ingressHandlerServer struct { + svc IngressHandlerServerImpl + rpc *psrpc.RPCServer +} + +// NewIngressHandlerServer builds a RPCServer that will route requests +// to the corresponding method in the provided svc implementation. +func NewIngressHandlerServer(serverID string, svc IngressHandlerServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (IngressHandlerServer, error) { + s := psrpc.NewRPCServer("IngressHandler", serverID, bus, opts...) + + return &ingressHandlerServer{ + svc: svc, + rpc: s, + }, nil +} + +func (s *ingressHandlerServer) RegisterUpdateIngressTopic(topic string) error { + return psrpc.RegisterHandler(s.rpc, "UpdateIngress", topic, s.svc.UpdateIngress, nil) +} + +func (s *ingressHandlerServer) DeregisterUpdateIngressTopic(topic string) { + s.rpc.DeregisterHandler("UpdateIngress", topic) +} + +func (s *ingressHandlerServer) RegisterDeleteIngressTopic(topic string) error { + return psrpc.RegisterHandler(s.rpc, "DeleteIngress", topic, s.svc.DeleteIngress, nil) +} + +func (s *ingressHandlerServer) DeregisterDeleteIngressTopic(topic string) { + s.rpc.DeregisterHandler("DeleteIngress", topic) +} + +func (s *ingressHandlerServer) Shutdown() { + s.rpc.Close(false) +} + +func (s *ingressHandlerServer) Kill() { + s.rpc.Close(true) +} + +var psrpcFileDescriptor1 = []byte{ + // 269 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcf, 0x4a, 0x03, 0x31, + 0x10, 0xc6, 0x89, 0x85, 0xa2, 0x91, 0x2a, 0x0d, 0x14, 0xea, 0x82, 0x7f, 0xd8, 0x93, 0x88, 0x64, + 0xa1, 0x5e, 0xbd, 0x28, 0x1e, 0x5c, 0xd0, 0x4b, 0xc5, 0x4b, 0x2f, 0x65, 0x9b, 0x1d, 0xd6, 0xd0, + 0x6d, 0x12, 0x33, 0xd3, 0x7d, 0x07, 0x5f, 0xc6, 0x83, 0x4f, 0x28, 0xda, 0xb1, 0xb8, 0xd8, 0x82, + 0xa7, 0xc0, 0xf7, 0x9b, 0xfc, 0xbe, 0x21, 0x91, 0xfd, 0x18, 0x4c, 0x66, 0x5d, 0x15, 0x01, 0x51, + 0x87, 0xe8, 0xc9, 0xab, 0x4e, 0x0c, 0x26, 0xe9, 0xf9, 0x40, 0xd6, 0x3b, 0xce, 0x92, 0x41, 0x6d, + 0x1b, 0x98, 0x5b, 0x9a, 0xb6, 0x46, 0xd3, 0x44, 0x0e, 0x1f, 0x2c, 0xd2, 0x8d, 0x21, 0xdb, 0x40, + 0xbe, 0x42, 0x63, 0x78, 0x5d, 0x02, 0x52, 0x7a, 0x2d, 0x8f, 0x36, 0x30, 0x0c, 0xde, 0x21, 0xa8, + 0x53, 0xb9, 0xcf, 0xa6, 0xa9, 0x2d, 0x71, 0x28, 0xce, 0x3a, 0xe7, 0x7b, 0x63, 0xc9, 0x51, 0x5e, + 0xe2, 0x68, 0x21, 0x0f, 0xf9, 0x4e, 0xee, 0x08, 0xa2, 0x2b, 0x6a, 0x35, 0x91, 0xfd, 0x3f, 0x42, + 0x75, 0xac, 0x63, 0x30, 0x7a, 0xdb, 0x12, 0xc9, 0xc9, 0x36, 0xbc, 0xda, 0x23, 0xed, 0x7e, 0xbc, + 0x89, 0x9d, 0x5d, 0x31, 0x7a, 0x17, 0xf2, 0x80, 0xd9, 0x7d, 0xe1, 0xca, 0x1a, 0xa2, 0x7a, 0x94, + 0xbd, 0xe7, 0x50, 0x16, 0xf4, 0xab, 0x8a, 0x1f, 0x41, 0xb7, 0xf2, 0x9f, 0xaa, 0xc1, 0x1a, 0x33, + 0x78, 0xa2, 0x82, 0xb8, 0x61, 0x28, 0xbe, 0x74, 0x77, 0x50, 0xc3, 0x26, 0x5d, 0x2b, 0xff, 0x9f, + 0xee, 0xf6, 0x72, 0x72, 0x51, 0x59, 0x7a, 0x59, 0xce, 0xb4, 0xf1, 0x8b, 0x8c, 0x47, 0xd7, 0x67, + 0x98, 0x57, 0x19, 0x42, 0x6c, 0xac, 0x81, 0x2c, 0x06, 0x33, 0xeb, 0x7e, 0x7f, 0xd7, 0xd5, 0x67, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0x7d, 0xaa, 0x66, 0xee, 0x01, 0x00, 0x00, +} diff --git a/rpc/ingress_client.go b/rpc/ingress_client.go new file mode 100644 index 00000000..7126a6c1 --- /dev/null +++ b/rpc/ingress_client.go @@ -0,0 +1,36 @@ +package rpc + +import ( + "github.com/livekit/protocol/livekit" + "github.com/livekit/psrpc" +) + +type IngressClient interface { + IngressInternalClient + IngressHandlerClient +} + +type ingressClient struct { + IngressInternalClient + IngressHandlerClient +} + +func NewIngressClient(nodeID livekit.NodeID, bus psrpc.MessageBus) (IngressClient, error) { + if bus == nil { + return nil, nil + } + + clientID := string(nodeID) + internalClient, err := NewIngressInternalClient(clientID, bus) + if err != nil { + return nil, err + } + handlerClient, err := NewIngressHandlerClient(clientID, bus) + if err != nil { + return nil, err + } + return &ingressClient{ + IngressInternalClient: internalClient, + IngressHandlerClient: handlerClient, + }, nil +} diff --git a/rpc/io.pb.go b/rpc/io.pb.go new file mode 100644 index 00000000..73b42466 --- /dev/null +++ b/rpc/io.pb.go @@ -0,0 +1,403 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: rpc/io.proto + +package rpc + +import ( + livekit "github.com/livekit/protocol/livekit" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Query an ingress info from an ingress ID or stream key +type GetIngressInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IngressId string `protobuf:"bytes,1,opt,name=ingress_id,json=ingressId,proto3" json:"ingress_id,omitempty"` + StreamKey string `protobuf:"bytes,2,opt,name=stream_key,json=streamKey,proto3" json:"stream_key,omitempty"` + // Deprecated: Do not use. + RequestId string `protobuf:"bytes,3,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // Deprecated: Do not use. + SenderId string `protobuf:"bytes,4,opt,name=sender_id,json=senderId,proto3" json:"sender_id,omitempty"` + // Deprecated: Do not use. + SentAt int64 `protobuf:"varint,5,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"` +} + +func (x *GetIngressInfoRequest) Reset() { + *x = GetIngressInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_io_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetIngressInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIngressInfoRequest) ProtoMessage() {} + +func (x *GetIngressInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_io_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIngressInfoRequest.ProtoReflect.Descriptor instead. +func (*GetIngressInfoRequest) Descriptor() ([]byte, []int) { + return file_rpc_io_proto_rawDescGZIP(), []int{0} +} + +func (x *GetIngressInfoRequest) GetIngressId() string { + if x != nil { + return x.IngressId + } + return "" +} + +func (x *GetIngressInfoRequest) GetStreamKey() string { + if x != nil { + return x.StreamKey + } + return "" +} + +// Deprecated: Do not use. +func (x *GetIngressInfoRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +// Deprecated: Do not use. +func (x *GetIngressInfoRequest) GetSenderId() string { + if x != nil { + return x.SenderId + } + return "" +} + +// Deprecated: Do not use. +func (x *GetIngressInfoRequest) GetSentAt() int64 { + if x != nil { + return x.SentAt + } + return 0 +} + +type GetIngressInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *livekit.IngressInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + WsUrl string `protobuf:"bytes,3,opt,name=ws_url,json=wsUrl,proto3" json:"ws_url,omitempty"` + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` + RequestId string `protobuf:"bytes,5,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` +} + +func (x *GetIngressInfoResponse) Reset() { + *x = GetIngressInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_io_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetIngressInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIngressInfoResponse) ProtoMessage() {} + +func (x *GetIngressInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_rpc_io_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIngressInfoResponse.ProtoReflect.Descriptor instead. +func (*GetIngressInfoResponse) Descriptor() ([]byte, []int) { + return file_rpc_io_proto_rawDescGZIP(), []int{1} +} + +func (x *GetIngressInfoResponse) GetInfo() *livekit.IngressInfo { + if x != nil { + return x.Info + } + return nil +} + +func (x *GetIngressInfoResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *GetIngressInfoResponse) GetWsUrl() string { + if x != nil { + return x.WsUrl + } + return "" +} + +func (x *GetIngressInfoResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *GetIngressInfoResponse) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +// Request to store an update to the ingress state ingress -> service +type UpdateIngressStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IngressId string `protobuf:"bytes,1,opt,name=ingress_id,json=ingressId,proto3" json:"ingress_id,omitempty"` + State *livekit.IngressState `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *UpdateIngressStateRequest) Reset() { + *x = UpdateIngressStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_io_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateIngressStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateIngressStateRequest) ProtoMessage() {} + +func (x *UpdateIngressStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_io_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateIngressStateRequest.ProtoReflect.Descriptor instead. +func (*UpdateIngressStateRequest) Descriptor() ([]byte, []int) { + return file_rpc_io_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateIngressStateRequest) GetIngressId() string { + if x != nil { + return x.IngressId + } + return "" +} + +func (x *UpdateIngressStateRequest) GetState() *livekit.IngressState { + if x != nil { + return x.State + } + return nil +} + +var File_rpc_io_proto protoreflect.FileDescriptor + +var file_rpc_io_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, + 0x72, 0x70, 0x63, 0x1a, 0x14, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x5f, 0x65, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x69, 0x76, 0x65, 0x6b, + 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, 0x01, + 0x0a, 0x15, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x08, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x07, 0x73, 0x65, 0x6e, + 0x74, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, + 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x22, 0xa4, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x28, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x77, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x77, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0x67, 0x0a, + 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, + 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x32, 0xe2, 0x01, 0x0a, 0x06, 0x49, 0x4f, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x3f, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x13, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, + 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, + 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x2c, 0x5a, 0x2a, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, + 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_rpc_io_proto_rawDescOnce sync.Once + file_rpc_io_proto_rawDescData = file_rpc_io_proto_rawDesc +) + +func file_rpc_io_proto_rawDescGZIP() []byte { + file_rpc_io_proto_rawDescOnce.Do(func() { + file_rpc_io_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_io_proto_rawDescData) + }) + return file_rpc_io_proto_rawDescData +} + +var file_rpc_io_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_rpc_io_proto_goTypes = []interface{}{ + (*GetIngressInfoRequest)(nil), // 0: rpc.GetIngressInfoRequest + (*GetIngressInfoResponse)(nil), // 1: rpc.GetIngressInfoResponse + (*UpdateIngressStateRequest)(nil), // 2: rpc.UpdateIngressStateRequest + (*livekit.IngressInfo)(nil), // 3: livekit.IngressInfo + (*livekit.IngressState)(nil), // 4: livekit.IngressState + (*livekit.EgressInfo)(nil), // 5: livekit.EgressInfo + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty +} +var file_rpc_io_proto_depIdxs = []int32{ + 3, // 0: rpc.GetIngressInfoResponse.info:type_name -> livekit.IngressInfo + 4, // 1: rpc.UpdateIngressStateRequest.state:type_name -> livekit.IngressState + 5, // 2: rpc.IOInfo.UpdateEgressInfo:input_type -> livekit.EgressInfo + 0, // 3: rpc.IOInfo.GetIngressInfo:input_type -> rpc.GetIngressInfoRequest + 2, // 4: rpc.IOInfo.UpdateIngressState:input_type -> rpc.UpdateIngressStateRequest + 6, // 5: rpc.IOInfo.UpdateEgressInfo:output_type -> google.protobuf.Empty + 1, // 6: rpc.IOInfo.GetIngressInfo:output_type -> rpc.GetIngressInfoResponse + 6, // 7: rpc.IOInfo.UpdateIngressState:output_type -> google.protobuf.Empty + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_rpc_io_proto_init() } +func file_rpc_io_proto_init() { + if File_rpc_io_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_io_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetIngressInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_io_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetIngressInfoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_io_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateIngressStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_io_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_rpc_io_proto_goTypes, + DependencyIndexes: file_rpc_io_proto_depIdxs, + MessageInfos: file_rpc_io_proto_msgTypes, + }.Build() + File_rpc_io_proto = out.File + file_rpc_io_proto_rawDesc = nil + file_rpc_io_proto_goTypes = nil + file_rpc_io_proto_depIdxs = nil +} diff --git a/rpc/io.proto b/rpc/io.proto new file mode 100644 index 00000000..059819ea --- /dev/null +++ b/rpc/io.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package rpc; + +option go_package = "github.com/livekit/livekit/pkg/service/rpc"; + +import "livekit_egress.proto"; +import "livekit_ingress.proto"; +import "google/protobuf/empty.proto"; + +service IOInfo { + rpc UpdateEgressInfo(livekit.EgressInfo) returns (google.protobuf.Empty); + rpc GetIngressInfo(GetIngressInfoRequest) returns (GetIngressInfoResponse); + rpc UpdateIngressState(UpdateIngressStateRequest) returns (google.protobuf.Empty); +} + +// Query an ingress info from an ingress ID or stream key +message GetIngressInfoRequest { + string ingress_id = 1; + string stream_key = 2; + string request_id = 3 [deprecated = true]; + string sender_id = 4 [deprecated = true]; + int64 sent_at = 5 [deprecated = true]; +} + +message GetIngressInfoResponse { + livekit.IngressInfo info = 1; + string token = 2; + string ws_url = 3; + string error = 4; + string request_id = 5; +} + +// Request to store an update to the ingress state ingress -> service +message UpdateIngressStateRequest { + string ingress_id = 1; + livekit.IngressState state = 2; +} diff --git a/rpc/io.psrpc.go b/rpc/io.psrpc.go new file mode 100644 index 00000000..ca47a800 --- /dev/null +++ b/rpc/io.psrpc.go @@ -0,0 +1,158 @@ +// Code generated by protoc-gen-psrpc v0.2.5, DO NOT EDIT. +// source: rpc/io.proto + +package rpc + +import context "context" +import psrpc "github.com/livekit/psrpc" +import version "github.com/livekit/psrpc/version" +import google_protobuf2 "google.golang.org/protobuf/types/known/emptypb" +import livekit "github.com/livekit/protocol/livekit" + +var _ = version.PsrpcVersion_0_2_5 + +// ======================= +// IOInfo Client Interface +// ======================= + +type IOInfoClient interface { + UpdateEgressInfo(context.Context, *livekit.EgressInfo, ...psrpc.RequestOption) (*google_protobuf2.Empty, error) + + GetIngressInfo(context.Context, *GetIngressInfoRequest, ...psrpc.RequestOption) (*GetIngressInfoResponse, error) + + UpdateIngressState(context.Context, *UpdateIngressStateRequest, ...psrpc.RequestOption) (*google_protobuf2.Empty, error) +} + +// =========================== +// IOInfo ServerImpl Interface +// =========================== + +type IOInfoServerImpl interface { + UpdateEgressInfo(context.Context, *livekit.EgressInfo) (*google_protobuf2.Empty, error) + + GetIngressInfo(context.Context, *GetIngressInfoRequest) (*GetIngressInfoResponse, error) + + UpdateIngressState(context.Context, *UpdateIngressStateRequest) (*google_protobuf2.Empty, error) +} + +// ======================= +// IOInfo Server Interface +// ======================= + +type IOInfoServer interface { + // Close and wait for pending RPCs to complete + Shutdown() + + // Close immediately, without waiting for pending RPCs + Kill() +} + +// ============= +// IOInfo Client +// ============= + +type iOInfoClient struct { + client *psrpc.RPCClient +} + +// NewIOInfoClient creates a psrpc client that implements the IOInfoClient interface. +func NewIOInfoClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOption) (IOInfoClient, error) { + rpcClient, err := psrpc.NewRPCClient("IOInfo", clientID, bus, opts...) + if err != nil { + return nil, err + } + + return &iOInfoClient{ + client: rpcClient, + }, nil +} + +func (c *iOInfoClient) UpdateEgressInfo(ctx context.Context, req *livekit.EgressInfo, opts ...psrpc.RequestOption) (*google_protobuf2.Empty, error) { + return psrpc.RequestSingle[*google_protobuf2.Empty](ctx, c.client, "UpdateEgressInfo", "", req, opts...) +} + +func (c *iOInfoClient) GetIngressInfo(ctx context.Context, req *GetIngressInfoRequest, opts ...psrpc.RequestOption) (*GetIngressInfoResponse, error) { + return psrpc.RequestSingle[*GetIngressInfoResponse](ctx, c.client, "GetIngressInfo", "", req, opts...) +} + +func (c *iOInfoClient) UpdateIngressState(ctx context.Context, req *UpdateIngressStateRequest, opts ...psrpc.RequestOption) (*google_protobuf2.Empty, error) { + return psrpc.RequestSingle[*google_protobuf2.Empty](ctx, c.client, "UpdateIngressState", "", req, opts...) +} + +// ============= +// IOInfo Server +// ============= + +type iOInfoServer struct { + svc IOInfoServerImpl + rpc *psrpc.RPCServer +} + +// NewIOInfoServer builds a RPCServer that will route requests +// to the corresponding method in the provided svc implementation. +func NewIOInfoServer(serverID string, svc IOInfoServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOption) (IOInfoServer, error) { + s := psrpc.NewRPCServer("IOInfo", serverID, bus, opts...) + + var err error + err = psrpc.RegisterHandler(s, "UpdateEgressInfo", "", svc.UpdateEgressInfo, nil) + if err != nil { + s.Close(false) + return nil, err + } + + err = psrpc.RegisterHandler(s, "GetIngressInfo", "", svc.GetIngressInfo, nil) + if err != nil { + s.Close(false) + return nil, err + } + + err = psrpc.RegisterHandler(s, "UpdateIngressState", "", svc.UpdateIngressState, nil) + if err != nil { + s.Close(false) + return nil, err + } + + return &iOInfoServer{ + svc: svc, + rpc: s, + }, nil +} + +func (s *iOInfoServer) Shutdown() { + s.rpc.Close(false) +} + +func (s *iOInfoServer) Kill() { + s.rpc.Close(true) +} + +var psrpcFileDescriptor2 = []byte{ + // 430 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xd1, 0x8a, 0xd3, 0x40, + 0x14, 0x25, 0xdb, 0x4d, 0xb5, 0x77, 0x45, 0x64, 0x6c, 0x97, 0x9a, 0xa2, 0xae, 0x7d, 0x2a, 0x2a, + 0x13, 0xa8, 0x1f, 0x20, 0x2e, 0x2c, 0x12, 0x14, 0x84, 0xc8, 0xbe, 0xf8, 0x12, 0xda, 0xe4, 0x36, + 0x0e, 0x49, 0x33, 0xe3, 0xcc, 0x64, 0x97, 0xfe, 0x8f, 0xdf, 0xe0, 0x07, 0xf9, 0x25, 0x32, 0xb9, + 0xb3, 0xb1, 0xae, 0x5b, 0xd8, 0xa7, 0x30, 0xe7, 0x9c, 0x3b, 0x73, 0xce, 0xc9, 0x85, 0x47, 0x5a, + 0xe5, 0xb1, 0x90, 0x5c, 0x69, 0x69, 0x25, 0x1b, 0x68, 0x95, 0x47, 0xe3, 0x5a, 0x5c, 0x61, 0x25, + 0x6c, 0x86, 0xa5, 0x46, 0x63, 0x88, 0x8a, 0x26, 0x37, 0xa8, 0x68, 0xf6, 0xe1, 0x59, 0x29, 0x65, + 0x59, 0x63, 0xdc, 0x9d, 0xd6, 0xed, 0x26, 0xc6, 0xad, 0xb2, 0x3b, 0x22, 0xe7, 0xbf, 0x02, 0x98, + 0x7c, 0x44, 0x9b, 0xd0, 0x44, 0xd2, 0x6c, 0x64, 0x8a, 0x3f, 0x5a, 0x34, 0x96, 0x3d, 0x07, 0xf0, + 0xf7, 0x64, 0xa2, 0x98, 0x06, 0x67, 0xc1, 0x62, 0x94, 0x8e, 0x3c, 0x92, 0x14, 0x8e, 0x36, 0x56, + 0xe3, 0x6a, 0x9b, 0x55, 0xb8, 0x9b, 0x1e, 0x11, 0x4d, 0xc8, 0x27, 0xdc, 0xb1, 0x57, 0x00, 0x9a, + 0x2e, 0x72, 0xd3, 0x03, 0x47, 0x9f, 0x1f, 0x4d, 0x83, 0x74, 0xe4, 0xd1, 0xa4, 0x60, 0x2f, 0x61, + 0x64, 0xb0, 0x29, 0x50, 0x3b, 0xc5, 0x71, 0xaf, 0x78, 0x48, 0x60, 0x52, 0xb0, 0x19, 0x3c, 0x30, + 0xd8, 0xd8, 0x6c, 0x65, 0xa7, 0xe1, 0x59, 0xb0, 0x18, 0x74, 0xf4, 0xd0, 0x41, 0x1f, 0xec, 0xfc, + 0x67, 0x00, 0xa7, 0xb7, 0x8d, 0x1b, 0x25, 0x1b, 0x83, 0x6c, 0x01, 0xc7, 0xa2, 0xd9, 0xc8, 0xce, + 0xf3, 0xc9, 0x72, 0xcc, 0x7d, 0x2d, 0x7c, 0x5f, 0xdb, 0x29, 0xd8, 0x18, 0x42, 0x2b, 0x2b, 0x6c, + 0xbc, 0x7f, 0x3a, 0xb0, 0x09, 0x0c, 0xaf, 0x4d, 0xd6, 0xea, 0x9a, 0x7c, 0xa7, 0xe1, 0xb5, 0xb9, + 0xd4, 0xb5, 0x13, 0xa3, 0xd6, 0x52, 0x93, 0xd7, 0x94, 0x0e, 0xae, 0x87, 0xbd, 0xa0, 0x21, 0xf5, + 0xd0, 0x87, 0x9c, 0x97, 0xf0, 0xec, 0x52, 0x15, 0x2b, 0x8b, 0xfe, 0xf1, 0xaf, 0x76, 0x65, 0xf1, + 0x9e, 0x15, 0xbf, 0x81, 0xd0, 0x38, 0x79, 0xe7, 0xee, 0x64, 0x39, 0xb9, 0x1d, 0x84, 0xee, 0x22, + 0xcd, 0xf2, 0x77, 0x00, 0xc3, 0xe4, 0x8b, 0xcb, 0xc6, 0xde, 0xc3, 0x13, 0x7a, 0xf3, 0xa2, 0xcf, + 0xcb, 0x9e, 0xf6, 0xc3, 0x7f, 0xc1, 0xe8, 0x94, 0xd3, 0x6a, 0xf0, 0x9b, 0xd5, 0xe0, 0x17, 0x6e, + 0x35, 0x58, 0x02, 0x8f, 0xff, 0xad, 0x96, 0x45, 0x5c, 0xab, 0x9c, 0xdf, 0xb9, 0x28, 0xd1, 0xec, + 0x4e, 0xce, 0xff, 0x8b, 0xcf, 0xc0, 0xfe, 0xcf, 0xcf, 0x5e, 0x74, 0x23, 0x07, 0x8b, 0x39, 0x64, + 0xec, 0xfc, 0xed, 0xb7, 0xd7, 0xa5, 0xb0, 0xdf, 0xdb, 0x35, 0xcf, 0xe5, 0x36, 0xf6, 0x89, 0xfa, + 0xaf, 0xaa, 0xca, 0xd8, 0xa0, 0xbe, 0x12, 0x39, 0xc6, 0x5a, 0xe5, 0xeb, 0x61, 0x37, 0xfd, 0xee, + 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0x59, 0x29, 0x79, 0x41, 0x03, 0x00, 0x00, +} diff --git a/rpc/race.go b/rpc/race.go new file mode 100644 index 00000000..5c482515 --- /dev/null +++ b/rpc/race.go @@ -0,0 +1,63 @@ +package rpc + +import ( + "context" + "sync" +) + +type raceResult[T any] struct { + i int + val *T + err error +} + +type Race[T any] struct { + ctx context.Context + cancel context.CancelFunc + nextIndex int + + resultLock sync.Mutex + result *raceResult[T] +} + +// NewRace creates a race to yield the result from one or more candidate +// functions +func NewRace[T any](ctx context.Context) *Race[T] { + ctx, cancel := context.WithCancel(ctx) + return &Race[T]{ + ctx: ctx, + cancel: cancel, + } +} + +// Go adds a candidate function to the race by running it in a new goroutine +func (r *Race[T]) Go(fn func(ctx context.Context) (*T, error)) { + i := r.nextIndex + r.nextIndex++ + + go func() { + val, err := fn(r.ctx) + + r.resultLock.Lock() + if r.result == nil { + r.result = &raceResult[T]{i, val, err} + } + r.resultLock.Unlock() + + r.cancel() + }() +} + +// Wait awaits the first complete function and returns the index and results +// or -1 if the context is cancelled before any candidate finishes. +func (r *Race[T]) Wait() (int, *T, error) { + <-r.ctx.Done() + + r.resultLock.Lock() + res := r.result + r.resultLock.Unlock() + if res != nil { + return res.i, res.val, res.err + } + return -1, nil, r.ctx.Err() +}