mirror of
https://github.com/hanzoai/psrpc.git
synced 2026-09-30 23:47:22 +00:00
protoc-gen-psrpc (#3)
* protoc-gen-psrpc * static check * install protoc-gen-go, add generate workflow * combine actions * add more testing * increate test timeouts * add small wait after subscribing * errors
This commit is contained in:
+20
-15
@@ -3,22 +3,18 @@ name: Test
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches-ignore: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
|
||||
- name: Install Protoc
|
||||
uses: arduino/setup-protoc@v1
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
~/go/bin
|
||||
~/.cache
|
||||
key: livekit-psrpc
|
||||
version: '3.x'
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
@@ -28,12 +24,14 @@ jobs:
|
||||
- name: Download Go modules
|
||||
run: go mod download
|
||||
|
||||
- name: Static Check
|
||||
uses: dominikh/staticcheck-action@v1.2.0
|
||||
- name: Install protoc-gen-go
|
||||
run: go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1
|
||||
|
||||
- name: Generate Protobuf
|
||||
uses: magefile/mage-action@v2
|
||||
with:
|
||||
min-go-version: 1.18
|
||||
version: 2022.1
|
||||
install-go: false
|
||||
version: latest
|
||||
args: proto
|
||||
|
||||
- name: Start Redis
|
||||
uses: supercharge/[email protected]
|
||||
@@ -45,4 +43,11 @@ jobs:
|
||||
uses: magefile/mage-action@v2
|
||||
with:
|
||||
version: latest
|
||||
args: test
|
||||
args: testall
|
||||
|
||||
- name: Add changes
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
add: livekit
|
||||
default_author: github_actions
|
||||
message: generated protobuf
|
||||
|
||||
@@ -3,339 +3,249 @@
|
||||
Create custom protobuf-based golang RPCs built on pub/sub.
|
||||
|
||||
Supports:
|
||||
* Redis or Nats as a backend
|
||||
* Protobuf service definitions
|
||||
* Redis or Nats as a communication layer
|
||||
* Custom server selection for RPC handling based on user-defined [affinity](#Affinity)
|
||||
* Single RPCs (RequestSingle) - one request is handled by one server, used for normal RPCs
|
||||
* Multi RPCs (RequestAll) - one request is handled by every server, used for distributed updates or result aggregation
|
||||
* Single RPC streams (JoinStreamQueue) - updates sent from the server will only be processed by a single client
|
||||
* Multi RPC streams (JoinStream) - updates sent be the server will be processed by every client
|
||||
* RPC topics - any RPC can be divided into topics, (e.g. by region)
|
||||
* Single RPCs - one request is handled by one server, used for normal RPCs
|
||||
* Multi RPCs - one request is handled by every server, used for distributed updates or result aggregation
|
||||
* Queue Subscriptions - updates sent from the server will only be processed by a single client
|
||||
* Subscriptions - updates sent be the server will be processed by every client
|
||||
|
||||
## Interfaces
|
||||
## Usage
|
||||
|
||||
### RPCServer
|
||||
### Protobuf
|
||||
|
||||
PSRPC is generated from proto files, and we've added a few custom method options:
|
||||
```protobuf
|
||||
message Options {
|
||||
// For RPCs, each client request will receive a response from every server.
|
||||
// For subscriptions, every client will receive every update.
|
||||
bool multi = 1;
|
||||
|
||||
// This method is a pub/sub.
|
||||
bool subscription = 2;
|
||||
|
||||
// This method uses topics.
|
||||
bool topics = 3;
|
||||
|
||||
// Your service will supply an affinity function for handler selection.
|
||||
bool affinity_func = 4;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Start with your service definition. Here's an example using different method options:
|
||||
|
||||
```protobuf
|
||||
syntax = "proto3";
|
||||
|
||||
import "options.proto";
|
||||
|
||||
option go_package = "/api";
|
||||
|
||||
service MyService {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
rpc NormalRPC(MyRequest) returns (MyResponse);
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
rpc IntensiveRPC(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).affinity_func = true;
|
||||
};
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
rpc GetStats(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).multi = true;
|
||||
};
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
rpc GetRegionStats(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).topics = true;
|
||||
option (psrpc.options).multi = true;
|
||||
}
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
// The request parameter (in this case, Ignored) will always be ignored when generating go files.
|
||||
rpc ProcessUpdate(Ignored) returns (MyUpdate) {
|
||||
option (psrpc.options).subscription = true;
|
||||
};
|
||||
|
||||
// A normal subscription - every client will receive every update.
|
||||
// The request parameter (in this case, Ignored) will always be ignored when generating go files.
|
||||
rpc UpdateState(Ignored) returns (MyUpdate) {
|
||||
option (psrpc.options).subscription = true;
|
||||
option (psrpc.options).multi = true;
|
||||
};
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
// The request parameter (in this case, Ignored) will always be ignored when generating go files.
|
||||
rpc UpdateRegionState(Ignored) returns (MyUpdate) {
|
||||
option (psrpc.options).subscription = true;
|
||||
option (psrpc.options).topics = true;
|
||||
option (psrpc.options).multi = true;
|
||||
}
|
||||
}
|
||||
|
||||
message Ignored {}
|
||||
message MyRequest {}
|
||||
message MyResponse {}
|
||||
message MyUpdate {}
|
||||
```
|
||||
|
||||
### Generation
|
||||
|
||||
Install `protoc-gen-psrpc` by running `go install github.com/livekit/psrpc/protoc-gen-psrpc`.
|
||||
|
||||
If using the custom options above, you'll also need to download [options.proto](protoc-gen-psrpc/options/options.proto).
|
||||
|
||||
Use the `--psrpc_out` with `protoc` and include the options file.
|
||||
|
||||
```shell
|
||||
protoc \
|
||||
--go_out=paths=source_relative:. \
|
||||
--psrpc_out=paths=source_relative:. \
|
||||
-I ./protoc-gen-psrpc/options \
|
||||
-I=. my_service.proto
|
||||
```
|
||||
|
||||
This will create a `my_service.psrpc.go` file
|
||||
|
||||
### Client
|
||||
|
||||
A `MyServiceClient` will be generated based on your rpc definitions:
|
||||
|
||||
```go
|
||||
type RPCServer interface {
|
||||
// register a handler
|
||||
RegisterHandler(h Handler) error
|
||||
type MyServiceClient interface {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
NormalRPC(ctx context.Context, req *MyRequest, opts ...psrpc.RequestOpt) (*MyResponse, error)
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
IntensiveRPC(ctx context.Context, req *MyRequest, opts ...psrpc.RequestOpt) (*MyResponse, error)
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
GetStats(ctx context.Context, req *MyRequest, opts ...psrpc.RequestOpt) (<-chan *psrpc.Response[*MyResponse], error)
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
GetRegionStats(ctx context.Context, topic string, req *Request, opts ...psrpc.RequestOpt) (<-chan *psrpc.Response[*MyResponse], error)
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
SubscribeProcessUpdate(ctx context.Context) (psrpc.Subscription[*MyUpdate], error)
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
SubscribeUpdateRegionState(ctx context.Context, topic string) (psrpc.Subscription[*MyUpdate], error)
|
||||
}
|
||||
|
||||
// publish updates to a streaming rpc
|
||||
PublishToStream(ctx context.Context, rpc string, message proto.Message) error
|
||||
|
||||
// stop listening for requests for a rpc
|
||||
DeregisterHandler(rpc string) error
|
||||
|
||||
// close all subscriptions and stop
|
||||
Close()
|
||||
// NewMyServiceClient creates a psrpc client that implements the MyServiceClient interface.
|
||||
func NewMyServiceClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (MyServiceClient, error) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### RPCClient
|
||||
|
||||
Multi-RPCs will return a `chan *psrpc.Response`, where you will receive an individual response or error from each server:
|
||||
```go
|
||||
// send a request to a single server, and receive one response
|
||||
func RequestSingle[ResponseType proto.Message](
|
||||
ctx context.Context,
|
||||
client RPCClient,
|
||||
rpc string,
|
||||
request proto.Message,
|
||||
opts ...RequestOption,
|
||||
) (ResponseType, error)
|
||||
|
||||
// send a request to all servers, and receive one response per server
|
||||
func RequestAll[ResponseType proto.Message](
|
||||
ctx context.Context,
|
||||
client RPCClient,
|
||||
rpc string,
|
||||
request proto.Message,
|
||||
opts ...RequestOption,
|
||||
) (<-chan *Response[ResponseType], error)
|
||||
|
||||
// subscribe to a streaming rpc (all subscribed clients will receive every message)
|
||||
func JoinStream[ResponseType proto.Message](
|
||||
ctx context.Context,
|
||||
client RPCClient,
|
||||
rpc string,
|
||||
) (Subscription[ResponseType], error)
|
||||
|
||||
// join a queue for a streaming rpc (each message is only received by a single client)
|
||||
func JoinStreamQueue[ResponseType proto.Message](
|
||||
ctx context.Context,
|
||||
client RPCClient,
|
||||
rpc string,
|
||||
) (Subscription[ResponseType], error)
|
||||
|
||||
// types
|
||||
type Response[ResponseType proto.Message] struct {
|
||||
Result ResponseType
|
||||
Err error
|
||||
}
|
||||
```
|
||||
|
||||
Subscription RPCs will return a `psrpc.Subscription`, where you can listen for updates on its channel:
|
||||
|
||||
```go
|
||||
type Subscription[MessageType proto.Message] interface {
|
||||
Channel() <-chan MessageType
|
||||
Close() error
|
||||
}
|
||||
```
|
||||
|
||||
### ServerImpl
|
||||
|
||||
A `<ServiceName>ServerImpl` interface will be also be generated from your rpcs. Your service will need to fulfill its interface:
|
||||
|
||||
```go
|
||||
type MyServiceServerImpl interface {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
NormalRPC(ctx context.Context, req *MyRequest) (*MyResponse, error)
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
IntensiveRPC(ctx context.Context, req *MyRequest) (*MyResponse, error)
|
||||
IntensiveRPCAffinity(req *MyRequest) float32
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
GetStats(ctx context.Context, req *MyRequest) (*MyResponse, error)
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
GetRegionStats(ctx context.Context, req *MyRequest) (*MyResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
### Server
|
||||
|
||||
Finally, a `<ServiceName>Server` will be generated. This is used to start your rpc server, as well as register and deregister topics:
|
||||
|
||||
```go
|
||||
type MyServiceServer interface {
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
RegisterGetRegionStatsTopic(topic string) error
|
||||
DeregisterGetRegionStatsTopic(topic string) error
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
PublishProcessUpdate(ctx context.Context, msg *MyUpdate) error
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
PublishUpdateRegionState(ctx context.Context, topic string, msg *MyUpdate) error
|
||||
}
|
||||
|
||||
// NewMyServiceServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewMyServiceServer(serverID string, svc MyServiceServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (MyServiceServer, error) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Affinity
|
||||
|
||||
### AffinityFunc
|
||||
|
||||
The server can register an AffinityFunc for the client to decide which instance should take a SingleRequest.
|
||||
The server can implement an affinity function for the client to decide which instance should take a SingleRequest.
|
||||
A higher affinity score is better, and a score of 0 means the server is not available.
|
||||
|
||||
For example, the following could be used to return an affinity based on cpu load:
|
||||
```protobuf
|
||||
rpc IntensiveRPC(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).affinity_func = true;
|
||||
};
|
||||
```
|
||||
|
||||
```go
|
||||
func main() {
|
||||
...
|
||||
rpcServer.RegisterHandler(psrpc.NewHandlerWithAffinity("MyRPC", handlerFunc, getAffinity))
|
||||
...
|
||||
func (s *MyService) IntensiveRPC(ctx context.Context, req *api.MyRequest) (*api.MyResponse, error) {
|
||||
... // do something CPU intensive
|
||||
}
|
||||
|
||||
func getAffinity(req *api.Request) float32 {
|
||||
func (s *MyService) IntensiveRPCAffinity(_ *MyRequest) float32 {
|
||||
return stats.GetIdleCPU()
|
||||
}
|
||||
```
|
||||
|
||||
### AffinityOptions
|
||||
### SelectionOpts
|
||||
|
||||
On the client side, you can also set affinity options for server selection with SendSingleRequest.
|
||||
|
||||
Affinity options:
|
||||
* AcceptFirstAvailable: if true, the first server to respond with an affinity greater than 0 and MinimumAffinity will be selected.
|
||||
* MinimumAffinity: Minimum affinity for a server to be considered a valid handler.
|
||||
* AffinityTimeout: if AcceptFirstAvailable is false, the client will wait this amount of time, then select the server with the highest affinity score.
|
||||
* ShortCircuitTimeout: if AcceptFirstAvailable is false, the client will wait this amount of time after receiving its first valid response, then select the server with the highest affinity score.
|
||||
|
||||
If no options are supplied, the client will choose the first server to respond with an affinity score > 0.
|
||||
On the client side, you can also set server selection options with single RPCs.
|
||||
|
||||
```go
|
||||
affinityOpts := psrpc.AffinityOpts{
|
||||
type SelectionOpts struct {
|
||||
MinimumAffinity float32 // (default 0) minimum affinity for a server to be considered a valid handler
|
||||
AcceptFirstAvailable bool // (default true)
|
||||
AffinityTimeout time.Duration // (default 0 (none)) server selection deadline
|
||||
ShortCircuitTimeout time.Duration // (default 0 (none)) deadline imposed after receiving first response
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
selectionOpts := psrpc.SelectionOpts{
|
||||
MinimumAffinity: 0.5,
|
||||
AffinityTimeout: time.Second,
|
||||
ShortCircuitTimeout: time.Millisecond * 250,
|
||||
}
|
||||
res, err := psrpc.RequestSingle[*api.Response](
|
||||
context.Background(),
|
||||
rpcClient,
|
||||
"MyRPC",
|
||||
&api.Request{},
|
||||
psrpc.WithAffinityOpts(affinityOpts))
|
||||
```
|
||||
|
||||
For a full example, see the [Advanced example](#Advanced) below.
|
||||
|
||||
## Examples
|
||||
|
||||
### SingleRequest
|
||||
|
||||
Proto:
|
||||
```protobuf
|
||||
package api;
|
||||
|
||||
message AddRequest {
|
||||
int32 increment = 1;
|
||||
}
|
||||
|
||||
message AddResult {
|
||||
int32 value = 1;
|
||||
}
|
||||
```
|
||||
|
||||
Server:
|
||||
```go
|
||||
func main() {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
serverID := "test_server"
|
||||
rpcServer := psrpc.NewRPCServer("CountingService", serverID, psrpc.NewRedisMessageBus(rc))
|
||||
|
||||
svc := &CountingService{}
|
||||
rpcServer.RegisterHandler(psrpc.NewHandler("AddValue", svc.AddValue))
|
||||
...
|
||||
}
|
||||
|
||||
type CountingService struct {
|
||||
counter atomic.Int32
|
||||
}
|
||||
|
||||
func (s *CountingService) AddValue(ctx context.Context, req *api.AddReqest) (*api.AddResult, error) {
|
||||
value := counter.Add(req.Increment)
|
||||
return &proto.AddResult{Value: value}, nil
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Client:
|
||||
```go
|
||||
func main() {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
clientID := "test_client"
|
||||
rpcClient := psrpc.NewRPCClient("CountingService", clientID, psrpc.NewRedisMessageBus(rc))
|
||||
|
||||
res, err := psrpc.RequestSingle[*api.AddResult](
|
||||
context.Background(),
|
||||
rpcClient,
|
||||
"AddValue",
|
||||
&api.AddRequest{Increment: 3})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(res.Value)
|
||||
}
|
||||
```
|
||||
|
||||
### MultiRequest
|
||||
|
||||
Proto:
|
||||
```protobuf
|
||||
package api;
|
||||
|
||||
message GetValueRequest {}
|
||||
|
||||
message ValueResult {
|
||||
int32 value = 1;
|
||||
}
|
||||
```
|
||||
|
||||
Server:
|
||||
```go
|
||||
func main() {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
serverID := "test_server"
|
||||
rpcServer := psrpc.NewRPCServer("CountingService", serverID, psrpc.NewRedisMessageBus(rc))
|
||||
|
||||
svc := &Service{}
|
||||
rpcServer.RegisterHandler(psrpc.NewHandler("GetValue", svc.GetValue))
|
||||
...
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
counter atomic.Int32
|
||||
}
|
||||
|
||||
func (s *Service) GetValue(ctx context.Context, req *api.GetValueRequest) (*api.ValueResult, error) {
|
||||
return &api.ValueResult{Value: s.counter.Load()}, nil
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Client:
|
||||
```go
|
||||
func main() {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
clientID := "test_client"
|
||||
rpcClient := psrpc.NewRPCClient("CountingService", clientID, psrpc.NewRedisMessageBus(rc))
|
||||
|
||||
sub, err := psrpc.RequestAll[*api.ValueResult](
|
||||
context.Background(),
|
||||
rpcClient,
|
||||
"GetValue",
|
||||
&api.GetValueRequest{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer sub.Close()
|
||||
|
||||
total := 0
|
||||
for {
|
||||
response, ok := <-sub.Channel()
|
||||
if !ok {
|
||||
// channel has been closed
|
||||
break
|
||||
}
|
||||
|
||||
if response.Err != nil {
|
||||
fmt.Println("error:", err)
|
||||
} else {
|
||||
total += response.Result.Value
|
||||
}
|
||||
}
|
||||
fmt.Println("total:", total)
|
||||
}
|
||||
```
|
||||
|
||||
### Advanced
|
||||
|
||||
Proto:
|
||||
```protobuf
|
||||
package api;
|
||||
|
||||
message CalculateUserStatsRequest {
|
||||
int64 from_unix_time = 1;
|
||||
int64 to_unix_time = 2;
|
||||
}
|
||||
|
||||
message CalculateUserStatsResponse {
|
||||
int32 unique_users = 1;
|
||||
int32 new_users = 2;
|
||||
int32 inactive_users = 3;
|
||||
int32 daily_active_users = 4;
|
||||
}
|
||||
```
|
||||
|
||||
Server:
|
||||
```go
|
||||
func main() {
|
||||
svc := NewProcessingService()
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
serverID := "test_server"
|
||||
rpcServer := psrpc.NewRPCServer("ProcessingService", serverID, psrpc.NewRedisMessageBus(rc))
|
||||
defer rpcServer.Close()
|
||||
|
||||
rpcServer.RegisterHandler(psrpc.NewHandlerWithAffinity("CalculateUserStats", svc.CalculateUserStats, getAffinity))
|
||||
...
|
||||
}
|
||||
|
||||
// The CalculateUserStats rpc requires a lot of CPU - use idle CPUs for the affinity metric
|
||||
func getAffinity(req *api.CalculateUserStatsRequest) float32 {
|
||||
return stats.GetIdleCPU()
|
||||
}
|
||||
|
||||
type ProcessingService struct {}
|
||||
|
||||
func (s *ProcessingService) CalculateUserStats(ctx context.Context, req *api.CalculateUserStatsRequest) (*api.CalculateUserStatsResponse, error) {
|
||||
userStats, err := getUserStats(req.FromUnixTime, req.ToUnixTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.CalculateUserStatsResponse{
|
||||
UniqueUsers: userStats.uniqueUsers,
|
||||
NewUsers: userStats.newUsers,
|
||||
InactiveUsers: userStats.inactiveUsers,
|
||||
DailyActiveUsers: userStats.dailyActiveUsers,
|
||||
}, nil
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Client:
|
||||
```go
|
||||
func main() {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
clientID := "test_client"
|
||||
rpcClient := psrpc.NewRPCClient("ProcessingService", clientID, psrpc.NewRedisMessageBus(rc))
|
||||
|
||||
req := &api.CalculateUserStatsRequest{
|
||||
FromUnixTime: time.Now().Add(-time.Day * 30).UnixNano(),
|
||||
ToUnixTime: time.Now().UnixNano()
|
||||
}
|
||||
|
||||
// allow one second for server selection, with at least 0.5 cpu available
|
||||
// once the first valid server is found, selection will occur 250ms later
|
||||
affinityOpts := psrpc.AffinityOpts{
|
||||
MinimumAffinity: 0.5,
|
||||
AffinityTimeout: time.Second,
|
||||
ShortCircuitTimeout: time.Millisecond * 250,
|
||||
}
|
||||
|
||||
res, err := psrpc.RequestSingle[*api.CalculateUserStatsResponse](
|
||||
context.Background(),
|
||||
rpcClient,
|
||||
"CalculateUserStats",
|
||||
req,
|
||||
psrpc.WithAffinityOpts(affinityOpts),
|
||||
psrpc.WithTimeout(time.Second * 30)) // this query takes a while for larger ranges, use a longer timeout
|
||||
fmt.Printf("%+v", res)
|
||||
}
|
||||
res, err := myClient.IntensiveRPC(ctx, req, psrpc.WithSelectionOpts(selectionOpts))
|
||||
```
|
||||
|
||||
@@ -22,6 +22,46 @@ type MessageBus interface {
|
||||
getNC() *nats.Conn
|
||||
}
|
||||
|
||||
type Subscription[MessageType proto.Message] interface {
|
||||
Channel() <-chan MessageType
|
||||
Close() error
|
||||
}
|
||||
|
||||
var ErrBusNotConnected = errors.New("bus not connected")
|
||||
|
||||
func Publish(bus MessageBus, ctx context.Context, channel string, msg proto.Message) error {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisPublish(bus.getRC(), ctx, channel, msg)
|
||||
case natsBus:
|
||||
return natsPublish(bus.getNC(), ctx, channel, msg)
|
||||
default:
|
||||
return ErrBusNotConnected
|
||||
}
|
||||
}
|
||||
|
||||
func Subscribe[MessageType proto.Message](bus MessageBus, ctx context.Context, channel string) (Subscription[MessageType], error) {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisSubscribe[MessageType](bus.getRC(), ctx, channel)
|
||||
case natsBus:
|
||||
return natsSubscribe[MessageType](bus.getNC(), ctx, channel)
|
||||
default:
|
||||
return nil, ErrBusNotConnected
|
||||
}
|
||||
}
|
||||
|
||||
func SubscribeQueue[MessageType proto.Message](bus MessageBus, ctx context.Context, channel string) (Subscription[MessageType], error) {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisSubscribeQueue[MessageType](bus.getRC(), ctx, channel)
|
||||
case natsBus:
|
||||
return natsSubscribeQueue[MessageType](bus.getNC(), ctx, channel)
|
||||
default:
|
||||
return nil, ErrBusNotConnected
|
||||
}
|
||||
}
|
||||
|
||||
type bus struct {
|
||||
MessageBus
|
||||
busType
|
||||
@@ -41,36 +81,3 @@ func (b *bus) getRC() redis.UniversalClient {
|
||||
func (b *bus) getNC() *nats.Conn {
|
||||
return b.nc
|
||||
}
|
||||
|
||||
func Publish(bus MessageBus, ctx context.Context, channel string, msg proto.Message) error {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisPublish(bus.getRC(), ctx, channel, msg)
|
||||
case natsBus:
|
||||
return natsPublish(bus.getNC(), ctx, channel, msg)
|
||||
default:
|
||||
return errors.New("not connected")
|
||||
}
|
||||
}
|
||||
|
||||
func Subscribe[MessageType proto.Message](bus MessageBus, ctx context.Context, channel string) (Subscription[MessageType], error) {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisSubscribe[MessageType](bus.getRC(), ctx, channel)
|
||||
case natsBus:
|
||||
return natsSubscribe[MessageType](bus.getNC(), ctx, channel)
|
||||
default:
|
||||
return nil, errors.New("not connected")
|
||||
}
|
||||
}
|
||||
|
||||
func SubscribeQueue[MessageType proto.Message](bus MessageBus, ctx context.Context, channel string) (Subscription[MessageType], error) {
|
||||
switch bus.getBusType() {
|
||||
case redisBus:
|
||||
return redisSubscribeQueue[MessageType](bus.getRC(), ctx, channel)
|
||||
case natsBus:
|
||||
return natsSubscribeQueue[MessageType](bus.getNC(), ctx, channel)
|
||||
default:
|
||||
return nil, errors.New("not connected")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||
github.com/livekit/mageutil v0.0.0-20221002073820-d9198083cfdc
|
||||
github.com/nats-io/nats.go v1.21.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
google.golang.org/protobuf v1.28.1
|
||||
)
|
||||
|
||||
@@ -34,6 +34,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
||||
+22
-7
@@ -2,7 +2,6 @@ package psrpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lithammer/shortuuid/v3"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -13,20 +12,36 @@ func newRequestID() string {
|
||||
return "REQ_" + shortuuid.New()[:12]
|
||||
}
|
||||
|
||||
func getRPCChannel(serviceName, rpc string) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s|%s|REQ", serviceName, rpc))
|
||||
func getRPCChannel(serviceName, rpc, topic string) string {
|
||||
if topic != "" {
|
||||
return fmt.Sprintf("%s|%s|%s|REQ", serviceName, rpc, topic)
|
||||
} else {
|
||||
return fmt.Sprintf("%s|%s|REQ", serviceName, rpc)
|
||||
}
|
||||
}
|
||||
|
||||
func getHandlerKey(rpc, topic string) string {
|
||||
if topic != "" {
|
||||
return fmt.Sprintf("%s|%s", rpc, topic)
|
||||
} else {
|
||||
return rpc
|
||||
}
|
||||
}
|
||||
|
||||
func getResponseChannel(serviceName, clientID string) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s|%s|RES", serviceName, clientID))
|
||||
return fmt.Sprintf("%s|%s|RES", serviceName, clientID)
|
||||
}
|
||||
|
||||
func getClaimRequestChannel(serviceName, clientID string) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s|%s|CLAIM", serviceName, clientID))
|
||||
return fmt.Sprintf("%s|%s|CLAIM", serviceName, clientID)
|
||||
}
|
||||
|
||||
func getClaimResponseChannel(serviceName, rpc string) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s|%s|RCLAIM", serviceName, rpc))
|
||||
func getClaimResponseChannel(serviceName, rpc, topic string) string {
|
||||
if topic != "" {
|
||||
return fmt.Sprintf("%s|%s|%s|RCLAIM", serviceName, rpc, topic)
|
||||
} else {
|
||||
return fmt.Sprintf("%s|%s|RCLAIM", serviceName, rpc)
|
||||
}
|
||||
}
|
||||
|
||||
func serialize(msg proto.Message) ([]byte, error) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Fail(msgs ...string) {
|
||||
s := strings.Join(msgs, " ")
|
||||
log.Print("error:", s)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Error(err error, msgs ...string) {
|
||||
s := strings.Join(msgs, " ") + ":" + err.Error()
|
||||
log.Print("error:", s)
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
plugin "google.golang.org/protobuf/types/pluginpb"
|
||||
)
|
||||
|
||||
type Generator interface {
|
||||
Generate(in *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse
|
||||
}
|
||||
|
||||
func Main(g Generator) {
|
||||
req := readGenRequest(os.Stdin)
|
||||
resp := g.Generate(req)
|
||||
writeResponse(os.Stdout, resp)
|
||||
}
|
||||
|
||||
func FilesToGenerate(req *plugin.CodeGeneratorRequest) []*descriptor.FileDescriptorProto {
|
||||
genFiles := make([]*descriptor.FileDescriptorProto, 0)
|
||||
Outer:
|
||||
for _, name := range req.FileToGenerate {
|
||||
for _, f := range req.ProtoFile {
|
||||
if f.GetName() == name {
|
||||
genFiles = append(genFiles, f)
|
||||
continue Outer
|
||||
}
|
||||
}
|
||||
Fail("could not find file named", name)
|
||||
}
|
||||
|
||||
return genFiles
|
||||
}
|
||||
|
||||
func readGenRequest(r io.Reader) *plugin.CodeGeneratorRequest {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
Error(err, "reading input")
|
||||
}
|
||||
|
||||
req := new(plugin.CodeGeneratorRequest)
|
||||
if err = proto.Unmarshal(data, req); err != nil {
|
||||
Error(err, "parsing input proto")
|
||||
}
|
||||
|
||||
if len(req.FileToGenerate) == 0 {
|
||||
Fail("no files to generate")
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
func writeResponse(w io.Writer, resp *plugin.CodeGeneratorResponse) {
|
||||
data, err := proto.Marshal(resp)
|
||||
if err != nil {
|
||||
Error(err, "marshaling response")
|
||||
}
|
||||
_, err = w.Write(data)
|
||||
if err != nil {
|
||||
Error(err, "writing response")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package stringutils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Is c an ASCII lower-case letter?
|
||||
func isASCIILower(c byte) bool {
|
||||
return 'a' <= c && c <= 'z'
|
||||
}
|
||||
|
||||
// Is c an ASCII digit?
|
||||
func isASCIIDigit(c byte) bool {
|
||||
return '0' <= c && c <= '9'
|
||||
}
|
||||
|
||||
// CamelCase converts a string from snake_case to CamelCased.
|
||||
//
|
||||
// If there is an interior underscore followed by a lower case letter, drop the
|
||||
// underscore and convert the letter to upper case. There is a remote
|
||||
// possibility of this rewrite causing a name collision, but it's so remote
|
||||
// we're prepared to pretend it's nonexistent - since the C++ generator
|
||||
// lowercases names, it's extremely unlikely to have two fields with different
|
||||
// capitalizations. In short, _my_field_name_2 becomes XMyFieldName_2.
|
||||
func CamelCase(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
t := make([]byte, 0, 32)
|
||||
i := 0
|
||||
if s[0] == '_' {
|
||||
// Need a capital letter; drop the '_'.
|
||||
t = append(t, 'X')
|
||||
i++
|
||||
}
|
||||
// Invariant: if the next letter is lower case, it must be converted
|
||||
// to upper case.
|
||||
//
|
||||
// That is, we process a word at a time, where words are marked by _ or upper
|
||||
// case letter. Digits are treated as words.
|
||||
for ; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
|
||||
continue // Skip the underscore in s.
|
||||
}
|
||||
if isASCIIDigit(c) {
|
||||
t = append(t, c)
|
||||
continue
|
||||
}
|
||||
// Assume we have a letter now - if not, it's a bogus identifier. The next
|
||||
// word is a sequence of characters that must start upper case.
|
||||
if isASCIILower(c) {
|
||||
c ^= ' ' // Make it a capital letter.
|
||||
}
|
||||
t = append(t, c) // Guaranteed not lower case.
|
||||
// Accept lower case sequence that follows.
|
||||
for i+1 < len(s) && isASCIILower(s[i+1]) {
|
||||
i++
|
||||
t = append(t, s[i])
|
||||
}
|
||||
}
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// AlphaDigitize replaces non-letter, non-digit, non-underscore characters with
|
||||
// underscore.
|
||||
func AlphaDigitize(r rune) rune {
|
||||
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
|
||||
return r
|
||||
}
|
||||
return '_'
|
||||
}
|
||||
|
||||
// CleanIdentifier makes sure s is a valid 'identifier' string: it contains only
|
||||
// letters, numbers, and underscore.
|
||||
func CleanIdentifier(s string) string {
|
||||
return strings.Map(AlphaDigitize, s)
|
||||
}
|
||||
|
||||
// BaseName the last path element of a slash-delimited name, with the last
|
||||
// dotted suffix removed.
|
||||
func BaseName(name string) string {
|
||||
// First, find the last element
|
||||
if i := strings.LastIndex(name, "/"); i >= 0 {
|
||||
name = name[i+1:]
|
||||
}
|
||||
// Now drop the suffix
|
||||
if i := strings.LastIndex(name, "."); i >= 0 {
|
||||
name = name[0:i]
|
||||
}
|
||||
return name
|
||||
}
|
||||
BIN
Binary file not shown.
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
//go:generate protoc --descriptor_set_out=fileset.pb --include_imports --include_source_info ./service.proto
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.gen.typemap.testdata.importer;
|
||||
|
||||
import "root_pkg.proto";
|
||||
|
||||
message ImporterMsg {
|
||||
root_pkg.RootMsg a = 1;
|
||||
|
||||
message ImporterInner {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.gen.typemap.testdata.public_importer;
|
||||
|
||||
import public "root_pkg.proto";
|
||||
import public "importer.proto";
|
||||
|
||||
message PublicImporterMsgA {
|
||||
importer.ImporterMsg a = 1;
|
||||
}
|
||||
|
||||
message PublicImporterMsgB {
|
||||
root_pkg.RootMsg a = 1;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.gen.typemap.testdata.public_reimporter;
|
||||
|
||||
import public "public_importer.proto";
|
||||
|
||||
message PublicReimporterMsg {
|
||||
public_importer.PublicImporterMsgA a = 1;
|
||||
public_importer.PublicImporterMsgB b = 2;
|
||||
root_pkg.RootMsg c = 3;
|
||||
importer.ImporterMsg d = 4;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.gen.typemap.testdata.root_pkg;
|
||||
|
||||
// RootMsg leading
|
||||
message RootMsg {}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.gen.typemap.testdata.public_reimporter;
|
||||
|
||||
import public "public_reimporter.proto";
|
||||
|
||||
message ServiceMsg {
|
||||
public_importer.PublicImporterMsgA a = 1;
|
||||
public_importer.PublicImporterMsgB b = 2;
|
||||
root_pkg.RootMsg c = 3;
|
||||
importer.ImporterMsg d = 4;
|
||||
}
|
||||
|
||||
message Parent {
|
||||
message NestedOuter{
|
||||
message NestedInner{}
|
||||
}
|
||||
}
|
||||
|
||||
service EmptyService {}
|
||||
|
||||
service ServiceWithOneMethod{
|
||||
// Method1 leading
|
||||
rpc Method1(root_pkg.RootMsg) returns (importer.ImporterMsg);
|
||||
// Method1 trailing
|
||||
}
|
||||
|
||||
// ServiceWithManyMethods leading
|
||||
service ServiceWithManyMethods{
|
||||
// Method1 leading
|
||||
rpc Method1(root_pkg.RootMsg) returns (importer.ImporterMsg);
|
||||
// Method2 leading
|
||||
rpc Method2(Parent) returns (Parent.NestedOuter);
|
||||
// Method2 trailing
|
||||
|
||||
rpc Method3(importer.ImporterMsg.ImporterInner) returns (Parent.NestedOuter.NestedInner);
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package typemap
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
type Registry struct {
|
||||
allFiles []*descriptor.FileDescriptorProto
|
||||
filesByName map[string]*descriptor.FileDescriptorProto
|
||||
|
||||
// Mapping of fully-qualified names to their definitions
|
||||
messagesByProtoName map[string]*MessageDefinition
|
||||
}
|
||||
|
||||
func New(files []*descriptor.FileDescriptorProto) *Registry {
|
||||
r := &Registry{
|
||||
allFiles: files,
|
||||
filesByName: make(map[string]*descriptor.FileDescriptorProto),
|
||||
messagesByProtoName: make(map[string]*MessageDefinition),
|
||||
}
|
||||
|
||||
// First, index the file descriptors by name. We need this so
|
||||
// messageDefsForFile can correctly scan imports.
|
||||
for _, f := range files {
|
||||
r.filesByName[f.GetName()] = f
|
||||
}
|
||||
|
||||
// Next, index all the message definitions by their fully-qualified proto
|
||||
// names.
|
||||
for _, f := range files {
|
||||
defs := messageDefsForFile(f, r.filesByName)
|
||||
for name, def := range defs {
|
||||
r.messagesByProtoName[name] = def
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Registry) FileComments(file *descriptor.FileDescriptorProto) (DefinitionComments, error) {
|
||||
return commentsAtPath([]int32{packagePath}, file), nil
|
||||
}
|
||||
|
||||
func (r *Registry) ServiceComments(file *descriptor.FileDescriptorProto, svc *descriptor.ServiceDescriptorProto) (DefinitionComments, error) {
|
||||
for i, s := range file.Service {
|
||||
if s == svc {
|
||||
path := []int32{servicePath, int32(i)}
|
||||
return commentsAtPath(path, file), nil
|
||||
}
|
||||
}
|
||||
return DefinitionComments{}, errors.Errorf("service not found in file")
|
||||
}
|
||||
|
||||
func (r *Registry) MethodComments(file *descriptor.FileDescriptorProto, svc *descriptor.ServiceDescriptorProto, method *descriptor.MethodDescriptorProto) (DefinitionComments, error) {
|
||||
for i, s := range file.Service {
|
||||
if s == svc {
|
||||
path := []int32{servicePath, int32(i)}
|
||||
for j, m := range s.Method {
|
||||
if m == method {
|
||||
path = append(path, serviceMethodPath, int32(j))
|
||||
return commentsAtPath(path, file), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DefinitionComments{}, errors.Errorf("service not found in file")
|
||||
}
|
||||
|
||||
func (r *Registry) MethodInputDefinition(method *descriptor.MethodDescriptorProto) *MessageDefinition {
|
||||
return r.messagesByProtoName[method.GetInputType()]
|
||||
}
|
||||
|
||||
func (r *Registry) MethodOutputDefinition(method *descriptor.MethodDescriptorProto) *MessageDefinition {
|
||||
return r.messagesByProtoName[method.GetOutputType()]
|
||||
}
|
||||
|
||||
func (r *Registry) MessageDefinition(name string) *MessageDefinition {
|
||||
return r.messagesByProtoName[name]
|
||||
}
|
||||
|
||||
type MessageDefinition struct {
|
||||
// Descriptor is the DescriptorProto defining the message.
|
||||
Descriptor *descriptor.DescriptorProto
|
||||
// File is the File that the message was defined in. Or, if it has been
|
||||
// publicly imported, what File was that import performed in?
|
||||
File *descriptor.FileDescriptorProto
|
||||
// Parent is the parent message, if this was defined as a nested message. If
|
||||
// this was defiend at the top level, parent is nil.
|
||||
Parent *MessageDefinition
|
||||
// Comments describes the comments surrounding a message's definition. If it
|
||||
// was publicly imported, then these comments are from the actual source file,
|
||||
// not the file that the import was performed in.
|
||||
Comments DefinitionComments
|
||||
|
||||
// path is the 'SourceCodeInfo' path. See the documentation for
|
||||
// google.golang.org/protobuf/types/descriptorpb.SourceCodeInfo for an
|
||||
// explanation of its format.
|
||||
path []int32
|
||||
}
|
||||
|
||||
// ProtoName returns the dot-delimited, fully-qualified protobuf name of the
|
||||
// message.
|
||||
func (m *MessageDefinition) ProtoName() string {
|
||||
prefix := "."
|
||||
if pkg := m.File.GetPackage(); pkg != "" {
|
||||
prefix += pkg + "."
|
||||
}
|
||||
|
||||
if lineage := m.Lineage(); len(lineage) > 0 {
|
||||
for _, parent := range lineage {
|
||||
prefix += parent.Descriptor.GetName() + "."
|
||||
}
|
||||
}
|
||||
|
||||
return prefix + m.Descriptor.GetName()
|
||||
}
|
||||
|
||||
// Lineage returns m's parental chain all the way back up to a top-level message
|
||||
// definition. The first element of the returned slice is the highest-level
|
||||
// parent.
|
||||
func (m *MessageDefinition) Lineage() []*MessageDefinition {
|
||||
var parents []*MessageDefinition
|
||||
for p := m.Parent; p != nil; p = p.Parent {
|
||||
parents = append([]*MessageDefinition{p}, parents...)
|
||||
}
|
||||
return parents
|
||||
}
|
||||
|
||||
// descendants returns all the submessages defined within m, and all the
|
||||
// descendants of those, recursively.
|
||||
func (m *MessageDefinition) descendants() []*MessageDefinition {
|
||||
descendants := make([]*MessageDefinition, 0)
|
||||
for i, child := range m.Descriptor.NestedType {
|
||||
path := append(m.path, []int32{messageMessagePath, int32(i)}...)
|
||||
childDef := &MessageDefinition{
|
||||
Descriptor: child,
|
||||
File: m.File,
|
||||
Parent: m,
|
||||
Comments: commentsAtPath(path, m.File),
|
||||
path: path,
|
||||
}
|
||||
descendants = append(descendants, childDef)
|
||||
descendants = append(descendants, childDef.descendants()...)
|
||||
}
|
||||
return descendants
|
||||
}
|
||||
|
||||
// messageDefsForFile gathers a mapping of fully-qualified protobuf names to
|
||||
// their definitions. It scans a singles file at a time. It requires a mapping
|
||||
// of .proto file names to their definitions in order to correctly handle
|
||||
// 'import public' declarations; this mapping should include all files
|
||||
// transitively imported by f.
|
||||
func messageDefsForFile(f *descriptor.FileDescriptorProto, filesByName map[string]*descriptor.FileDescriptorProto) map[string]*MessageDefinition {
|
||||
byProtoName := make(map[string]*MessageDefinition)
|
||||
// First, gather all the messages defined at the top level.
|
||||
for i, d := range f.MessageType {
|
||||
path := []int32{messagePath, int32(i)}
|
||||
def := &MessageDefinition{
|
||||
Descriptor: d,
|
||||
File: f,
|
||||
Parent: nil,
|
||||
Comments: commentsAtPath(path, f),
|
||||
path: path,
|
||||
}
|
||||
|
||||
byProtoName[def.ProtoName()] = def
|
||||
// Next, all nested message definitions.
|
||||
for _, child := range def.descendants() {
|
||||
byProtoName[child.ProtoName()] = child
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, all messages imported publicly.
|
||||
for _, depIdx := range f.PublicDependency {
|
||||
depFileName := f.Dependency[depIdx]
|
||||
depFile := filesByName[depFileName]
|
||||
depDefs := messageDefsForFile(depFile, filesByName)
|
||||
for _, def := range depDefs {
|
||||
imported := &MessageDefinition{
|
||||
Descriptor: def.Descriptor,
|
||||
File: f,
|
||||
Parent: def.Parent,
|
||||
Comments: commentsAtPath(def.path, depFile),
|
||||
path: def.path,
|
||||
}
|
||||
byProtoName[imported.ProtoName()] = imported
|
||||
}
|
||||
}
|
||||
|
||||
return byProtoName
|
||||
}
|
||||
|
||||
// DefinitionComments contains the comments surrounding a definition in a
|
||||
// protobuf file.
|
||||
//
|
||||
// These follow the rules described by protobuf:
|
||||
//
|
||||
// A series of line comments appearing on consecutive lines, with no other
|
||||
// tokens appearing on those lines, will be treated as a single comment.
|
||||
//
|
||||
// leading_detached_comments will keep paragraphs of comments that appear
|
||||
// before (but not connected to) the current element. Each paragraph,
|
||||
// separated by empty lines, will be one comment element in the repeated
|
||||
// field.
|
||||
//
|
||||
// Only the comment content is provided; comment markers (e.g. //) are
|
||||
// stripped out. For block comments, leading whitespace and an asterisk
|
||||
// will be stripped from the beginning of each line other than the first.
|
||||
// Newlines are included in the output.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// optional int32 foo = 1; // Comment attached to foo.
|
||||
// // Comment attached to bar.
|
||||
// optional int32 bar = 2;
|
||||
//
|
||||
// optional string baz = 3;
|
||||
// // Comment attached to baz.
|
||||
// // Another line attached to baz.
|
||||
//
|
||||
// // Comment attached to qux.
|
||||
// //
|
||||
// // Another line attached to qux.
|
||||
// optional double qux = 4;
|
||||
//
|
||||
// // Detached comment for corge. This is not leading or trailing comments
|
||||
// // to qux or corge because there are blank lines separating it from
|
||||
// // both.
|
||||
//
|
||||
// // Detached comment for corge paragraph 2.
|
||||
//
|
||||
// optional string corge = 5;
|
||||
// /* Block comment attached
|
||||
// * to corge. Leading asterisks
|
||||
// * will be removed. */
|
||||
// /* Block comment attached to
|
||||
// * grault. */
|
||||
// optional int32 grault = 6;
|
||||
//
|
||||
// // ignored detached comments.
|
||||
type DefinitionComments struct {
|
||||
Leading string
|
||||
Trailing string
|
||||
LeadingDetached []string
|
||||
}
|
||||
|
||||
func commentsAtPath(path []int32, sourceFile *descriptor.FileDescriptorProto) DefinitionComments {
|
||||
if sourceFile.SourceCodeInfo == nil {
|
||||
// The compiler didn't provide us with comments.
|
||||
return DefinitionComments{}
|
||||
}
|
||||
|
||||
for _, loc := range sourceFile.SourceCodeInfo.Location {
|
||||
if pathEqual(path, loc.Path) {
|
||||
return DefinitionComments{
|
||||
Leading: loc.GetLeadingComments(),
|
||||
LeadingDetached: loc.GetLeadingDetachedComments(),
|
||||
Trailing: loc.GetTrailingComments(),
|
||||
}
|
||||
}
|
||||
}
|
||||
return DefinitionComments{}
|
||||
}
|
||||
|
||||
func pathEqual(path1, path2 []int32) bool {
|
||||
if len(path1) != len(path2) {
|
||||
return false
|
||||
}
|
||||
for i, v := range path1 {
|
||||
if path2[i] != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
// tag numbers in FileDescriptorProto
|
||||
packagePath = 2 // package
|
||||
messagePath = 4 // message_type
|
||||
// enumPath = 5 // enum_type
|
||||
servicePath = 6 // service
|
||||
// tag numbers in DescriptorProto
|
||||
// messageFieldPath = 2 // field
|
||||
messageMessagePath = 3 // nested_type
|
||||
// messageEnumPath = 4 // enum_type
|
||||
// messageOneofPath = 8 // oneof_decl
|
||||
// tag numbers in ServiceDescriptorProto
|
||||
// serviceNamePath = 1 // name
|
||||
serviceMethodPath = 2 // method
|
||||
// serviceOptionsPath = 3 // options
|
||||
// tag numbers in MethodDescriptorProto
|
||||
// methodNamePath = 1 // name
|
||||
// methodInputPath = 2 // input_type
|
||||
// methodOutputPath = 3 // output_type
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package typemap
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
func loadTestPb(t *testing.T) []*descriptor.FileDescriptorProto {
|
||||
f, err := os.ReadFile(filepath.Join("testdata", "fileset.pb"))
|
||||
require.NoError(t, err, "unable to read testdata protobuf file")
|
||||
|
||||
set := new(descriptor.FileDescriptorSet)
|
||||
err = proto.Unmarshal(f, set)
|
||||
require.NoError(t, err, "unable to unmarshal testdata protobuf file")
|
||||
|
||||
return set.File
|
||||
}
|
||||
|
||||
func protoFile(files []*descriptor.FileDescriptorProto, name string) *descriptor.FileDescriptorProto {
|
||||
for _, f := range files {
|
||||
if filepath.Base(f.GetName()) == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func service(f *descriptor.FileDescriptorProto, name string) *descriptor.ServiceDescriptorProto {
|
||||
for _, s := range f.Service {
|
||||
if s.GetName() == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func method(s *descriptor.ServiceDescriptorProto, name string) *descriptor.MethodDescriptorProto {
|
||||
for _, m := range s.Method {
|
||||
if m.GetName() == name {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestNewRegistry(t *testing.T) {
|
||||
files := loadTestPb(t)
|
||||
file := protoFile(files, "service.proto")
|
||||
service := service(file, "ServiceWithManyMethods")
|
||||
|
||||
reg := New(files)
|
||||
|
||||
comments, err := reg.ServiceComments(file, service)
|
||||
require.NoError(t, err, "unable to load service comments")
|
||||
assert.Equal(t, " ServiceWithManyMethods leading\n", comments.Leading)
|
||||
|
||||
method1 := method(service, "Method1")
|
||||
require.NotNil(t, method1)
|
||||
|
||||
method1Input := reg.MethodInputDefinition(method1)
|
||||
require.NotNil(t, method1Input)
|
||||
assert.Equal(t, "RootMsg", method1Input.Descriptor.GetName())
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package gen
|
||||
|
||||
const Version = "v0.0.1"
|
||||
+45
-45
@@ -309,45 +309,45 @@ var File_internal_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_internal_proto_rawDesc = []byte{
|
||||
0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x12, 0x07, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07,
|
||||
0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73,
|
||||
0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75,
|
||||
0x6c, 0x74, 0x69, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0xa7, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07,
|
||||
0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73,
|
||||
0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08, 0x72,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x66, 0x0a,
|
||||
0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
|
||||
0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x66, 0x66,
|
||||
0x69, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x66, 0x66,
|
||||
0x69, 0x6e, 0x69, 0x74, 0x79, 0x22, 0x4b, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x49, 0x64, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x12, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
|
||||
0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||
0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d,
|
||||
0x75, 0x6c, 0x74, 0x69, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x72, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x22, 0xa7, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
|
||||
0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||
0x73, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08,
|
||||
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x66,
|
||||
0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a,
|
||||
0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x66,
|
||||
0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x61, 0x66,
|
||||
0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x22, 0x4b, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x49, 0x64, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -364,15 +364,15 @@ func file_internal_proto_rawDescGZIP() []byte {
|
||||
|
||||
var file_internal_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_internal_proto_goTypes = []interface{}{
|
||||
(*Request)(nil), // 0: livekit.Request
|
||||
(*Response)(nil), // 1: livekit.Response
|
||||
(*ClaimRequest)(nil), // 2: livekit.ClaimRequest
|
||||
(*ClaimResponse)(nil), // 3: livekit.ClaimResponse
|
||||
(*Request)(nil), // 0: internal.Request
|
||||
(*Response)(nil), // 1: internal.Response
|
||||
(*ClaimRequest)(nil), // 2: internal.ClaimRequest
|
||||
(*ClaimResponse)(nil), // 3: internal.ClaimResponse
|
||||
(*anypb.Any)(nil), // 4: google.protobuf.Any
|
||||
}
|
||||
var file_internal_proto_depIdxs = []int32{
|
||||
4, // 0: livekit.Request.request:type_name -> google.protobuf.Any
|
||||
4, // 1: livekit.Response.response:type_name -> google.protobuf.Any
|
||||
4, // 0: internal.Request.request:type_name -> google.protobuf.Any
|
||||
4, // 1: internal.Response.response:type_name -> google.protobuf.Any
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package livekit;
|
||||
package internal;
|
||||
option go_package = "github.com/livekit/psrpc/internal";
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package empty_service
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: empty_service.proto
|
||||
|
||||
package empty_service
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_empty_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_empty_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x13, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x42, 0x10, 0x5a, 0x0e, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_empty_service_proto_goTypes = []interface{}{}
|
||||
var file_empty_service_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] 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_empty_service_proto_init() }
|
||||
func file_empty_service_proto_init() {
|
||||
if File_empty_service_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_empty_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_empty_service_proto_goTypes,
|
||||
DependencyIndexes: file_empty_service_proto_depIdxs,
|
||||
}.Build()
|
||||
File_empty_service_proto = out.File
|
||||
file_empty_service_proto_rawDesc = nil
|
||||
file_empty_service_proto_goTypes = nil
|
||||
file_empty_service_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.emptyservice;
|
||||
|
||||
// Test to make sure that a service with no methods doesn't break.
|
||||
option go_package = "/empty_service";
|
||||
|
||||
service Empty{}
|
||||
@@ -0,0 +1,77 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: empty_service.proto
|
||||
|
||||
package empty_service
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// ======================
|
||||
// Empty Client Interface
|
||||
// ======================
|
||||
|
||||
type EmptyClient interface {
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// Empty ServerImpl Interface
|
||||
// ==========================
|
||||
|
||||
type EmptyServerImpl interface {
|
||||
}
|
||||
|
||||
// ======================
|
||||
// Empty Server Interface
|
||||
// ======================
|
||||
|
||||
type EmptyServer interface {
|
||||
}
|
||||
|
||||
// ============
|
||||
// Empty Client
|
||||
// ============
|
||||
|
||||
type emptyClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewEmptyClient creates a psrpc client that implements the EmptyClient interface.
|
||||
func NewEmptyClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (EmptyClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Empty", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &emptyClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ============
|
||||
// Empty Server
|
||||
// ============
|
||||
|
||||
type emptyServer struct {
|
||||
svc EmptyServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewEmptyServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewEmptyServer(serverID string, svc EmptyServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (EmptyServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Empty", serverID, bus, opts...)
|
||||
|
||||
return &emptyServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 90 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xcd, 0x2d, 0x28,
|
||||
0xa9, 0x8c, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17,
|
||||
0x52, 0x28, 0x28, 0x2e, 0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1,
|
||||
0x2b, 0x49, 0x2d, 0x2e, 0xd1, 0x03, 0x2b, 0x84, 0xaa, 0x33, 0x62, 0xe7, 0x62, 0x75, 0x05, 0xf1,
|
||||
0x9d, 0x04, 0xa2, 0xf8, 0xf4, 0x51, 0x8c, 0x48, 0x62, 0x03, 0x9b, 0x61, 0x0c, 0x08, 0x00, 0x00,
|
||||
0xff, 0xff, 0x16, 0x6b, 0xfe, 0x68, 0x5a, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package empty_service
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. empty_service.proto
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package google_protobuf_imports
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package google_protobuf_imports
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. service.proto
|
||||
@@ -0,0 +1,79 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: service.proto
|
||||
|
||||
package google_protobuf_imports
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||
0x1d, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x74, 0x65, 0x73, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 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, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61,
|
||||
0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x43, 0x0a, 0x03, 0x53,
|
||||
0x76, 0x63, 0x12, 0x3c, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 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, 0x1a, 0x5a, 0x18, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_service_proto_goTypes = []interface{}{
|
||||
(*wrapperspb.StringValue)(nil), // 0: google.protobuf.StringValue
|
||||
(*emptypb.Empty)(nil), // 1: google.protobuf.Empty
|
||||
}
|
||||
var file_service_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.use_empty.Svc.Send:input_type -> google.protobuf.StringValue
|
||||
1, // 1: psrpc.internal.test.use_empty.Svc.Send:output_type -> google.protobuf.Empty
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_service_proto_init() }
|
||||
func file_service_proto_init() {
|
||||
if File_service_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_service_proto_goTypes,
|
||||
DependencyIndexes: file_service_proto_depIdxs,
|
||||
}.Build()
|
||||
File_service_proto = out.File
|
||||
file_service_proto_rawDesc = nil
|
||||
file_service_proto_goTypes = nil
|
||||
file_service_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.use_empty;
|
||||
option go_package = "/google_protobuf_imports";
|
||||
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
service Svc {
|
||||
rpc Send(google.protobuf.StringValue) returns(google.protobuf.Empty);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: service.proto
|
||||
|
||||
package google_protobuf_imports
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
import google_protobuf "google.golang.org/protobuf/types/known/emptypb"
|
||||
import google_protobuf1 "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
|
||||
// ====================
|
||||
// Svc Client Interface
|
||||
// ====================
|
||||
|
||||
type SvcClient interface {
|
||||
Send(context.Context, *google_protobuf1.StringValue, ...psrpc.RequestOpt) (*google_protobuf.Empty, error)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// Svc ServerImpl Interface
|
||||
// ========================
|
||||
|
||||
type SvcServerImpl interface {
|
||||
Send(context.Context, *google_protobuf1.StringValue) (*google_protobuf.Empty, error)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// Svc Server Interface
|
||||
// ====================
|
||||
|
||||
type SvcServer interface {
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Client
|
||||
// ==========
|
||||
|
||||
type svcClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvcClient creates a psrpc client that implements the SvcClient interface.
|
||||
func NewSvcClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (SvcClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svcClient) Send(ctx context.Context, req *google_protobuf1.StringValue, opts ...psrpc.RequestOpt) (*google_protobuf.Empty, error) {
|
||||
return psrpc.RequestTopicSingle[*google_protobuf.Empty](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Server
|
||||
// ==========
|
||||
|
||||
type svcServer struct {
|
||||
svc SvcServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvcServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvcServer(serverID string, svc SvcServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (SvcServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 166 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0xcd, 0xbf, 0x0a, 0xc2, 0x40,
|
||||
0x0c, 0xc7, 0xf1, 0x41, 0x71, 0x28, 0xb8, 0x74, 0x10, 0x39, 0xff, 0x3c, 0x42, 0x0a, 0xba, 0x3a,
|
||||
0x29, 0x3e, 0x41, 0xc1, 0xc1, 0xa5, 0xb4, 0x35, 0x96, 0x83, 0xf6, 0x2e, 0x24, 0xb9, 0x8a, 0x6f,
|
||||
0x2f, 0xde, 0xd1, 0x45, 0xd7, 0xdf, 0xe7, 0x1b, 0x92, 0x2d, 0x05, 0x79, 0xb4, 0x2d, 0x02, 0xb1,
|
||||
0x57, 0x9f, 0xef, 0x48, 0x98, 0x5a, 0xb0, 0x4e, 0x91, 0x5d, 0xdd, 0x83, 0xa2, 0x28, 0x04, 0xc1,
|
||||
0x0a, 0x07, 0xd2, 0xb7, 0xd9, 0x74, 0xde, 0x77, 0x3d, 0x16, 0x31, 0x6e, 0xc2, 0xb3, 0x88, 0x73,
|
||||
0xba, 0x35, 0xfb, 0x5f, 0x7c, 0x71, 0x4d, 0x84, 0x2c, 0xc9, 0x0f, 0x97, 0x6c, 0x56, 0x8e, 0x6d,
|
||||
0x7e, 0xca, 0xe6, 0x25, 0xba, 0x47, 0xbe, 0x85, 0xd4, 0xc3, 0xd4, 0x43, 0xa9, 0x6c, 0x5d, 0x77,
|
||||
0xab, 0xfb, 0x80, 0x66, 0xf5, 0xa7, 0xd7, 0xef, 0xab, 0xb3, 0xb9, 0xaf, 0x8b, 0x24, 0xd5, 0x24,
|
||||
0x95, 0x1d, 0xc8, 0xb3, 0x4a, 0xb3, 0x88, 0xcb, 0xf1, 0x13, 0x00, 0x00, 0xff, 0xff, 0x0a, 0xfa,
|
||||
0x30, 0x79, 0xd4, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importable
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importable
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. importable.proto
|
||||
@@ -0,0 +1,144 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: importable.proto
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
|
||||
package importable
|
||||
|
||||
import (
|
||||
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 Msg struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg) Reset() {
|
||||
*x = Msg{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_importable_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_importable_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 Msg.ProtoReflect.Descriptor instead.
|
||||
func (*Msg) Descriptor() ([]byte, []int) {
|
||||
return file_importable_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_importable_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_importable_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x1e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x22, 0x05, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x32, 0x57, 0x0a, 0x03, 0x53, 0x76, 0x63,
|
||||
0x12, 0x50, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x23, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69,
|
||||
0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x1a, 0x23, 0x2e,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x4d,
|
||||
0x73, 0x67, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x69, 0x6d, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_importable_proto_rawDescOnce sync.Once
|
||||
file_importable_proto_rawDescData = file_importable_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_importable_proto_rawDescGZIP() []byte {
|
||||
file_importable_proto_rawDescOnce.Do(func() {
|
||||
file_importable_proto_rawDescData = protoimpl.X.CompressGZIP(file_importable_proto_rawDescData)
|
||||
})
|
||||
return file_importable_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_importable_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_importable_proto_goTypes = []interface{}{
|
||||
(*Msg)(nil), // 0: psrpc.internal.test.importable.Msg
|
||||
}
|
||||
var file_importable_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.importable.Svc.Send:input_type -> psrpc.internal.test.importable.Msg
|
||||
0, // 1: psrpc.internal.test.importable.Svc.Send:output_type -> psrpc.internal.test.importable.Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_importable_proto_init() }
|
||||
func file_importable_proto_init() {
|
||||
if File_importable_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_importable_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg); 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_importable_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_importable_proto_goTypes,
|
||||
DependencyIndexes: file_importable_proto_depIdxs,
|
||||
MessageInfos: file_importable_proto_msgTypes,
|
||||
}.Build()
|
||||
File_importable_proto = out.File
|
||||
file_importable_proto_rawDesc = nil
|
||||
file_importable_proto_goTypes = nil
|
||||
file_importable_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
package psrpc.internal.test.importable;
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/importable";
|
||||
|
||||
message Msg {}
|
||||
|
||||
service Svc {
|
||||
rpc Send(Msg) returns(Msg);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: importable.proto
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
|
||||
package importable
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// ====================
|
||||
// Svc Client Interface
|
||||
// ====================
|
||||
|
||||
type SvcClient interface {
|
||||
Send(context.Context, *Msg, ...psrpc.RequestOpt) (*Msg, error)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// Svc ServerImpl Interface
|
||||
// ========================
|
||||
|
||||
type SvcServerImpl interface {
|
||||
Send(context.Context, *Msg) (*Msg, error)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// Svc Server Interface
|
||||
// ====================
|
||||
|
||||
type SvcServer interface {
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Client
|
||||
// ==========
|
||||
|
||||
type svcClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvcClient creates a psrpc client that implements the SvcClient interface.
|
||||
func NewSvcClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (SvcClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svcClient) Send(ctx context.Context, req *Msg, opts ...psrpc.RequestOpt) (*Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Server
|
||||
// ==========
|
||||
|
||||
type svcServer struct {
|
||||
svc SvcServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvcServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvcServer(serverID string, svc SvcServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (SvcServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 140 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0xcc, 0x2d, 0xc8,
|
||||
0x2f, 0x2a, 0x49, 0x4c, 0xca, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x2b, 0x28,
|
||||
0x2e, 0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2b, 0x49, 0x2d,
|
||||
0x2e, 0xd1, 0x43, 0xa8, 0x52, 0x62, 0xe5, 0x62, 0xf6, 0x2d, 0x4e, 0x37, 0x0a, 0xe7, 0x62, 0x0e,
|
||||
0x2e, 0x4b, 0x16, 0x0a, 0xe0, 0x62, 0x09, 0x4e, 0xcd, 0x4b, 0x11, 0x52, 0xd6, 0xc3, 0xaf, 0x4d,
|
||||
0xcf, 0xb7, 0x38, 0x5d, 0x8a, 0x18, 0x45, 0x4e, 0xc6, 0x51, 0x86, 0xe9, 0x99, 0x25, 0x19, 0xa5,
|
||||
0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x39, 0x99, 0x65, 0xa9, 0xd9, 0x99, 0x25, 0xfa, 0x60, 0x8d,
|
||||
0xfa, 0x30, 0x8d, 0xfa, 0x20, 0x8d, 0xfa, 0x08, 0x8d, 0x49, 0x6c, 0x60, 0xb7, 0x1b, 0x03, 0x02,
|
||||
0x00, 0x00, 0xff, 0xff, 0xb6, 0xdf, 0xe8, 0x19, 0xcf, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importer
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importer
|
||||
|
||||
//go:generate protoc -I=. -I=../importable --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. importer.proto
|
||||
@@ -0,0 +1,79 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: importer.proto
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
|
||||
package importer
|
||||
|
||||
import (
|
||||
importable "github.com/livekit/psrpc/internal/test/importable"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_importer_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_importer_proto_rawDesc = []byte{
|
||||
0x0a, 0x0e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x12, 0x1c, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x1a, 0x10,
|
||||
0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x32, 0x58, 0x0a, 0x04, 0x53, 0x76, 0x63, 0x32, 0x12, 0x50, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64,
|
||||
0x12, 0x23, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x2e, 0x4d, 0x73, 0x67, 0x1a, 0x23, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
|
||||
0x2f, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
||||
0x74, 0x65, 0x73, 0x74, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_importer_proto_goTypes = []interface{}{
|
||||
(*importable.Msg)(nil), // 0: psrpc.internal.test.importable.Msg
|
||||
}
|
||||
var file_importer_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.importer.Svc2.Send:input_type -> psrpc.internal.test.importable.Msg
|
||||
0, // 1: psrpc.internal.test.importer.Svc2.Send:output_type -> psrpc.internal.test.importable.Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_importer_proto_init() }
|
||||
func file_importer_proto_init() {
|
||||
if File_importer_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_importer_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_importer_proto_goTypes,
|
||||
DependencyIndexes: file_importer_proto_depIdxs,
|
||||
}.Build()
|
||||
File_importer_proto = out.File
|
||||
file_importer_proto_rawDesc = nil
|
||||
file_importer_proto_goTypes = nil
|
||||
file_importer_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
package psrpc.internal.test.importer;
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/importer";
|
||||
|
||||
import "importable.proto";
|
||||
|
||||
service Svc2 {
|
||||
rpc Send(importable.Msg) returns(importable.Msg);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: importer.proto
|
||||
|
||||
// Test to make sure that importing other packages doesnt break
|
||||
|
||||
package importer
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
import psrpc_internal_test_importable "github.com/livekit/psrpc/internal/test/importable"
|
||||
|
||||
// =====================
|
||||
// Svc2 Client Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Client interface {
|
||||
Send(context.Context, *psrpc_internal_test_importable.Msg, ...psrpc.RequestOpt) (*psrpc_internal_test_importable.Msg, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Svc2 ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type Svc2ServerImpl interface {
|
||||
Send(context.Context, *psrpc_internal_test_importable.Msg) (*psrpc_internal_test_importable.Msg, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Svc2 Server Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Server interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Client
|
||||
// ===========
|
||||
|
||||
type svc2Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvc2Client creates a psrpc client that implements the Svc2Client interface.
|
||||
func NewSvc2Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (Svc2Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc2", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svc2Client) Send(ctx context.Context, req *psrpc_internal_test_importable.Msg, opts ...psrpc.RequestOpt) (*psrpc_internal_test_importable.Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*psrpc_internal_test_importable.Msg](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Server
|
||||
// ===========
|
||||
|
||||
type svc2Server struct {
|
||||
svc Svc2ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvc2Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvc2Server(serverID string, svc Svc2ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (Svc2Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc2", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 143 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0xcc, 0x2d, 0xc8,
|
||||
0x2f, 0x2a, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x29, 0x28, 0x2e, 0x2a,
|
||||
0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2b, 0x49, 0x2d, 0x2e, 0xd1,
|
||||
0x83, 0xa9, 0x91, 0x12, 0x80, 0xb0, 0x12, 0x93, 0x72, 0x52, 0x21, 0xea, 0x8d, 0x22, 0xb8, 0x58,
|
||||
0x82, 0xcb, 0x92, 0x8d, 0x84, 0x02, 0xb8, 0x58, 0x82, 0x53, 0xf3, 0x52, 0x84, 0x94, 0xf5, 0x70,
|
||||
0x1b, 0x00, 0xd6, 0xe6, 0x5b, 0x9c, 0x2e, 0x45, 0x8c, 0x22, 0x27, 0xc3, 0x28, 0xfd, 0xf4, 0xcc,
|
||||
0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0x9c, 0xcc, 0xb2, 0xd4, 0xec, 0xcc, 0x12,
|
||||
0x7d, 0xb0, 0x46, 0x7d, 0x98, 0x46, 0x7d, 0x90, 0x46, 0x7d, 0x98, 0xf3, 0x92, 0xd8, 0xc0, 0x6e,
|
||||
0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x10, 0x21, 0xbe, 0xd5, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importer_local
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importer_local
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. importer_local_msgdef.proto
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. importer_local.proto
|
||||
@@ -0,0 +1,79 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: importer_local.proto
|
||||
|
||||
package importer_local
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_importer_local_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_importer_local_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x1a, 0x1b, 0x69, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x67, 0x64, 0x65,
|
||||
0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x5f, 0x0a, 0x03, 0x53, 0x76, 0x63, 0x12, 0x58,
|
||||
0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x27, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x4d, 0x73, 0x67, 0x1a,
|
||||
0x27, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70,
|
||||
0x73, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65,
|
||||
0x73, 0x74, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_importer_local_proto_goTypes = []interface{}{
|
||||
(*Msg)(nil), // 0: psrpc.internal.test.importer_local.Msg
|
||||
}
|
||||
var file_importer_local_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.importer_local.Svc.Send:input_type -> psrpc.internal.test.importer_local.Msg
|
||||
0, // 1: psrpc.internal.test.importer_local.Svc.Send:output_type -> psrpc.internal.test.importer_local.Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_importer_local_proto_init() }
|
||||
func file_importer_local_proto_init() {
|
||||
if File_importer_local_proto != nil {
|
||||
return
|
||||
}
|
||||
file_importer_local_msgdef_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_importer_local_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_importer_local_proto_goTypes,
|
||||
DependencyIndexes: file_importer_local_proto_depIdxs,
|
||||
}.Build()
|
||||
File_importer_local_proto = out.File
|
||||
file_importer_local_proto_rawDesc = nil
|
||||
file_importer_local_proto_goTypes = nil
|
||||
file_importer_local_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.importer_local;
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/importer_local";
|
||||
|
||||
import "importer_local_msgdef.proto";
|
||||
|
||||
service Svc {
|
||||
rpc Send(Msg) returns (Msg);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: importer_local.proto
|
||||
|
||||
package importer_local
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// ====================
|
||||
// Svc Client Interface
|
||||
// ====================
|
||||
|
||||
type SvcClient interface {
|
||||
Send(context.Context, *Msg, ...psrpc.RequestOpt) (*Msg, error)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// Svc ServerImpl Interface
|
||||
// ========================
|
||||
|
||||
type SvcServerImpl interface {
|
||||
Send(context.Context, *Msg) (*Msg, error)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// Svc Server Interface
|
||||
// ====================
|
||||
|
||||
type SvcServer interface {
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Client
|
||||
// ==========
|
||||
|
||||
type svcClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvcClient creates a psrpc client that implements the SvcClient interface.
|
||||
func NewSvcClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (SvcClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svcClient) Send(ctx context.Context, req *Msg, opts ...psrpc.RequestOpt) (*Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Server
|
||||
// ==========
|
||||
|
||||
type svcServer struct {
|
||||
svc SvcServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvcServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvcServer(serverID string, svc SvcServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (SvcServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 150 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc9, 0xcc, 0x2d, 0xc8,
|
||||
0x2f, 0x2a, 0x49, 0x2d, 0x8a, 0xcf, 0xc9, 0x4f, 0x4e, 0xcc, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9,
|
||||
0x17, 0x52, 0x2a, 0x28, 0x2e, 0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc,
|
||||
0xd1, 0x2b, 0x49, 0x2d, 0x2e, 0xd1, 0x43, 0x55, 0x29, 0x25, 0x8d, 0xca, 0x8f, 0xcf, 0x2d, 0x4e,
|
||||
0x4f, 0x49, 0x4d, 0x83, 0x18, 0x60, 0x14, 0xcf, 0xc5, 0x1c, 0x5c, 0x96, 0x2c, 0x14, 0xc1, 0xc5,
|
||||
0x12, 0x9c, 0x9a, 0x97, 0x22, 0xa4, 0xae, 0x47, 0xd8, 0x40, 0x3d, 0xdf, 0xe2, 0x74, 0x29, 0x62,
|
||||
0x15, 0x3a, 0x99, 0x47, 0x99, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea,
|
||||
0xe7, 0x64, 0x96, 0xa5, 0x66, 0x67, 0x96, 0xe8, 0x83, 0x35, 0xeb, 0xc3, 0x34, 0xeb, 0x83, 0x34,
|
||||
0xeb, 0xa3, 0x6a, 0x4e, 0x62, 0x03, 0x3b, 0xd0, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x18, 0x5a,
|
||||
0x95, 0x49, 0xf9, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: importer_local_msgdef.proto
|
||||
|
||||
package importer_local
|
||||
|
||||
import (
|
||||
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 Msg struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg) Reset() {
|
||||
*x = Msg{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_importer_local_msgdef_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_importer_local_msgdef_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 Msg.ProtoReflect.Descriptor instead.
|
||||
func (*Msg) Descriptor() ([]byte, []int) {
|
||||
return file_importer_local_msgdef_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_importer_local_msgdef_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_importer_local_msgdef_proto_rawDesc = []byte{
|
||||
0x0a, 0x1b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
|
||||
0x5f, 0x6d, 0x73, 0x67, 0x64, 0x65, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x70,
|
||||
0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65,
|
||||
0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x22, 0x05, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70,
|
||||
0x73, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65,
|
||||
0x73, 0x74, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_importer_local_msgdef_proto_rawDescOnce sync.Once
|
||||
file_importer_local_msgdef_proto_rawDescData = file_importer_local_msgdef_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_importer_local_msgdef_proto_rawDescGZIP() []byte {
|
||||
file_importer_local_msgdef_proto_rawDescOnce.Do(func() {
|
||||
file_importer_local_msgdef_proto_rawDescData = protoimpl.X.CompressGZIP(file_importer_local_msgdef_proto_rawDescData)
|
||||
})
|
||||
return file_importer_local_msgdef_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_importer_local_msgdef_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_importer_local_msgdef_proto_goTypes = []interface{}{
|
||||
(*Msg)(nil), // 0: psrpc.internal.test.importer_local.Msg
|
||||
}
|
||||
var file_importer_local_msgdef_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] 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_importer_local_msgdef_proto_init() }
|
||||
func file_importer_local_msgdef_proto_init() {
|
||||
if File_importer_local_msgdef_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_importer_local_msgdef_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg); 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_importer_local_msgdef_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_importer_local_msgdef_proto_goTypes,
|
||||
DependencyIndexes: file_importer_local_msgdef_proto_depIdxs,
|
||||
MessageInfos: file_importer_local_msgdef_proto_msgTypes,
|
||||
}.Build()
|
||||
File_importer_local_msgdef_proto = out.File
|
||||
file_importer_local_msgdef_proto_rawDesc = nil
|
||||
file_importer_local_msgdef_proto_goTypes = nil
|
||||
file_importer_local_msgdef_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.importer_local;
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/importer_local";
|
||||
|
||||
message Msg {}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importmapping
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package importmapping
|
||||
|
||||
//go:generate ./gen.sh
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
protoc --go_out=. --psrpc_out=. \
|
||||
--go_opt=paths=source_relative \
|
||||
--go_opt=My/y.proto=github.com/livekit/psrpc/internal/test/importmapping/y \
|
||||
--psrpc_opt=paths=source_relative \
|
||||
--psrpc_opt=My/y.proto=github.com/livekit/psrpc/internal/test/importmapping/y \
|
||||
y/y.proto
|
||||
|
||||
protoc --go_out=. --psrpc_out=. \
|
||||
--go_opt=paths=source_relative \
|
||||
--go_opt=My/y.proto=github.com/livekit/psrpc/internal/test/importmapping/y \
|
||||
--go_opt=Mx/x.proto=github.com/livekit/psrpc/internal/test/importmapping/x \
|
||||
--psrpc_opt=paths=source_relative \
|
||||
--psrpc_opt=My/y.proto=github.com/livekit/psrpc/internal/test/importmapping/y \
|
||||
--psrpc_opt=Mx/x.proto=github.com/livekit/psrpc/internal/test/importmapping/x \
|
||||
x/x.proto
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Pull into variable since both protoc-gen-go and protoc-gen-psrpc need the map.
|
||||
Y_IMPORT_MAPPING="y/y.proto=github.com/livekit/psrpc/internal/test/importmapping/y"
|
||||
|
||||
PROTOC_GEN_GO_PARAMS="M${Y_IMPORT_MAPPING}" \
|
||||
PROTOC_GEN_PSRPC_PARAMS="go_import_mapping@${Y_IMPORT_MAPPING}" \
|
||||
../../protoc_gen.sh x/x.proto
|
||||
@@ -0,0 +1,76 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: x/x.proto
|
||||
|
||||
package x
|
||||
|
||||
import (
|
||||
y "github.com/livekit/psrpc/internal/test/importmapping/y"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_x_x_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_x_x_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x78, 0x2f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x70, 0x73, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74,
|
||||
0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x78,
|
||||
0x1a, 0x09, 0x79, 0x2f, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x64, 0x0a, 0x04, 0x53,
|
||||
0x76, 0x63, 0x31, 0x12, 0x5c, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x29, 0x2e, 0x70, 0x73,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e,
|
||||
0x79, 0x2e, 0x4d, 0x73, 0x67, 0x59, 0x1a, 0x29, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x6d, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x79, 0x2e, 0x4d, 0x73, 0x67,
|
||||
0x59, 0x42, 0x1f, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x77, 0x69, 0x6c, 0x6c, 0x2f, 0x62, 0x65, 0x2f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64,
|
||||
0x2f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_x_x_proto_goTypes = []interface{}{
|
||||
(*y.MsgY)(nil), // 0: psrpc.internal.test.importmapping.y.MsgY
|
||||
}
|
||||
var file_x_x_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.importmapping.x.Svc1.Send:input_type -> psrpc.internal.test.importmapping.y.MsgY
|
||||
0, // 1: psrpc.internal.test.importmapping.x.Svc1.Send:output_type -> psrpc.internal.test.importmapping.y.MsgY
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_x_x_proto_init() }
|
||||
func file_x_x_proto_init() {
|
||||
if File_x_x_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_x_x_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_x_x_proto_goTypes,
|
||||
DependencyIndexes: file_x_x_proto_depIdxs,
|
||||
}.Build()
|
||||
File_x_x_proto = out.File
|
||||
file_x_x_proto_rawDesc = nil
|
||||
file_x_x_proto_goTypes = nil
|
||||
file_x_x_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.importmapping.x;
|
||||
option go_package = "example.com/will/be/ignored/x";
|
||||
|
||||
import "y/y.proto";
|
||||
|
||||
service Svc1 {
|
||||
rpc Send(y.MsgY) returns (y.MsgY);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: x/x.proto
|
||||
|
||||
package x
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
import psrpc_internal_test_importmapping_y "github.com/livekit/psrpc/internal/test/importmapping/y"
|
||||
|
||||
// =====================
|
||||
// Svc1 Client Interface
|
||||
// =====================
|
||||
|
||||
type Svc1Client interface {
|
||||
Send(context.Context, *psrpc_internal_test_importmapping_y.MsgY, ...psrpc.RequestOpt) (*psrpc_internal_test_importmapping_y.MsgY, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Svc1 ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type Svc1ServerImpl interface {
|
||||
Send(context.Context, *psrpc_internal_test_importmapping_y.MsgY) (*psrpc_internal_test_importmapping_y.MsgY, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Svc1 Server Interface
|
||||
// =====================
|
||||
|
||||
type Svc1Server interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc1 Client
|
||||
// ===========
|
||||
|
||||
type svc1Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvc1Client creates a psrpc client that implements the Svc1Client interface.
|
||||
func NewSvc1Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (Svc1Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc1", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc1Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svc1Client) Send(ctx context.Context, req *psrpc_internal_test_importmapping_y.MsgY, opts ...psrpc.RequestOpt) (*psrpc_internal_test_importmapping_y.MsgY, error) {
|
||||
return psrpc.RequestTopicSingle[*psrpc_internal_test_importmapping_y.MsgY](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc1 Server
|
||||
// ===========
|
||||
|
||||
type svc1Server struct {
|
||||
svc Svc1ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvc1Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvc1Server(serverID string, svc Svc1ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (Svc1Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc1", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc1Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 147 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xce, 0x3d, 0x0a, 0x02, 0x31,
|
||||
0x10, 0x40, 0xe1, 0x66, 0x11, 0x76, 0xcb, 0x94, 0x0b, 0x62, 0x61, 0x65, 0x33, 0x83, 0x7a, 0x03,
|
||||
0x7b, 0xab, 0xad, 0x14, 0x9b, 0x6c, 0x32, 0x84, 0x40, 0x7e, 0x86, 0x24, 0xe8, 0xe4, 0xf6, 0x82,
|
||||
0x1e, 0x40, 0xfb, 0x8f, 0xc7, 0x9b, 0x46, 0x41, 0x01, 0x2e, 0xb9, 0x65, 0xb5, 0xe7, 0x5a, 0xd8,
|
||||
0x80, 0x4f, 0x8d, 0x4a, 0xd2, 0x01, 0x1a, 0xd5, 0x06, 0x3e, 0x72, 0x2e, 0x2d, 0x6a, 0x66, 0x9f,
|
||||
0x1c, 0xc8, 0x3c, 0x76, 0xec, 0x5f, 0x7f, 0xb2, 0xd3, 0xb0, 0x3c, 0xcd, 0x51, 0x3d, 0xa6, 0x61,
|
||||
0xa1, 0x64, 0xd5, 0x01, 0x7e, 0x07, 0x3a, 0x5c, 0xab, 0xbb, 0xcd, 0xff, 0xd3, 0xcb, 0xee, 0xbe,
|
||||
0x25, 0xd1, 0x91, 0x03, 0x81, 0xc9, 0x11, 0x5f, 0x3e, 0x04, 0x5c, 0x09, 0xbd, 0x4b, 0xb9, 0x90,
|
||||
0x45, 0x59, 0x37, 0x9f, 0x9b, 0xf3, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x6b, 0x1a, 0xa1, 0xca,
|
||||
0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: y/y.proto
|
||||
|
||||
package y
|
||||
|
||||
import (
|
||||
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 MsgY struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *MsgY) Reset() {
|
||||
*x = MsgY{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_y_y_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MsgY) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MsgY) ProtoMessage() {}
|
||||
|
||||
func (x *MsgY) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_y_y_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 MsgY.ProtoReflect.Descriptor instead.
|
||||
func (*MsgY) Descriptor() ([]byte, []int) {
|
||||
return file_y_y_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_y_y_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_y_y_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x79, 0x2f, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x70, 0x73, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74,
|
||||
0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x79,
|
||||
0x22, 0x06, 0x0a, 0x04, 0x4d, 0x73, 0x67, 0x59, 0x42, 0x1f, 0x5a, 0x1d, 0x65, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x69, 0x6c, 0x6c, 0x2f, 0x62, 0x65, 0x2f,
|
||||
0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2f, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_y_y_proto_rawDescOnce sync.Once
|
||||
file_y_y_proto_rawDescData = file_y_y_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_y_y_proto_rawDescGZIP() []byte {
|
||||
file_y_y_proto_rawDescOnce.Do(func() {
|
||||
file_y_y_proto_rawDescData = protoimpl.X.CompressGZIP(file_y_y_proto_rawDescData)
|
||||
})
|
||||
return file_y_y_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_y_y_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_y_y_proto_goTypes = []interface{}{
|
||||
(*MsgY)(nil), // 0: psrpc.internal.test.importmapping.y.MsgY
|
||||
}
|
||||
var file_y_y_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] 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_y_y_proto_init() }
|
||||
func file_y_y_proto_init() {
|
||||
if File_y_y_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_y_y_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MsgY); 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_y_y_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_y_y_proto_goTypes,
|
||||
DependencyIndexes: file_y_y_proto_depIdxs,
|
||||
MessageInfos: file_y_y_proto_msgTypes,
|
||||
}.Build()
|
||||
File_y_y_proto = out.File
|
||||
file_y_y_proto_rawDesc = nil
|
||||
file_y_y_proto_goTypes = nil
|
||||
file_y_y_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.importmapping.y;
|
||||
option go_package = "example.com/will/be/ignored/y";
|
||||
|
||||
message MsgY {}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package multiple
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. multiple1.proto multiple2.proto
|
||||
@@ -0,0 +1,142 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: multiple1.proto
|
||||
|
||||
// Multiple proto files in one package
|
||||
|
||||
package multiple
|
||||
|
||||
import (
|
||||
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 Msg1 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg1) Reset() {
|
||||
*x = Msg1{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_multiple1_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg1) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg1) ProtoMessage() {}
|
||||
|
||||
func (x *Msg1) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_multiple1_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 Msg1.ProtoReflect.Descriptor instead.
|
||||
func (*Msg1) Descriptor() ([]byte, []int) {
|
||||
return file_multiple1_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_multiple1_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_multiple1_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x1c, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x22,
|
||||
0x06, 0x0a, 0x04, 0x4d, 0x73, 0x67, 0x31, 0x32, 0x56, 0x0a, 0x04, 0x53, 0x76, 0x63, 0x31, 0x12,
|
||||
0x4e, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x22, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x6d, 0x75,
|
||||
0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x31, 0x1a, 0x22, 0x2e, 0x70, 0x73,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x31, 0x42,
|
||||
0x0b, 0x5a, 0x09, 0x2f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_multiple1_proto_rawDescOnce sync.Once
|
||||
file_multiple1_proto_rawDescData = file_multiple1_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_multiple1_proto_rawDescGZIP() []byte {
|
||||
file_multiple1_proto_rawDescOnce.Do(func() {
|
||||
file_multiple1_proto_rawDescData = protoimpl.X.CompressGZIP(file_multiple1_proto_rawDescData)
|
||||
})
|
||||
return file_multiple1_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_multiple1_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_multiple1_proto_goTypes = []interface{}{
|
||||
(*Msg1)(nil), // 0: psrpc.internal.test.multiple.Msg1
|
||||
}
|
||||
var file_multiple1_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.multiple.Svc1.Send:input_type -> psrpc.internal.test.multiple.Msg1
|
||||
0, // 1: psrpc.internal.test.multiple.Svc1.Send:output_type -> psrpc.internal.test.multiple.Msg1
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_multiple1_proto_init() }
|
||||
func file_multiple1_proto_init() {
|
||||
if File_multiple1_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_multiple1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg1); 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_multiple1_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_multiple1_proto_goTypes,
|
||||
DependencyIndexes: file_multiple1_proto_depIdxs,
|
||||
MessageInfos: file_multiple1_proto_msgTypes,
|
||||
}.Build()
|
||||
File_multiple1_proto = out.File
|
||||
file_multiple1_proto_rawDesc = nil
|
||||
file_multiple1_proto_goTypes = nil
|
||||
file_multiple1_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Multiple proto files in one package
|
||||
package psrpc.internal.test.multiple;
|
||||
option go_package = "/multiple";
|
||||
|
||||
message Msg1 {}
|
||||
|
||||
service Svc1 {
|
||||
rpc Send(Msg1) returns (Msg1);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: multiple1.proto
|
||||
|
||||
// Multiple proto files in one package
|
||||
|
||||
package multiple
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// =====================
|
||||
// Svc1 Client Interface
|
||||
// =====================
|
||||
|
||||
type Svc1Client interface {
|
||||
Send(context.Context, *Msg1, ...psrpc.RequestOpt) (*Msg1, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Svc1 ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type Svc1ServerImpl interface {
|
||||
Send(context.Context, *Msg1) (*Msg1, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Svc1 Server Interface
|
||||
// =====================
|
||||
|
||||
type Svc1Server interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc1 Client
|
||||
// ===========
|
||||
|
||||
type svc1Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvc1Client creates a psrpc client that implements the Svc1Client interface.
|
||||
func NewSvc1Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (Svc1Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc1", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc1Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svc1Client) Send(ctx context.Context, req *Msg1, opts ...psrpc.RequestOpt) (*Msg1, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg1](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc1 Server
|
||||
// ===========
|
||||
|
||||
type svc1Server struct {
|
||||
svc Svc1ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvc1Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvc1Server(serverID string, svc Svc1ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (Svc1Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc1", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc1Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 113 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcf, 0x2d, 0xcd, 0x29,
|
||||
0xc9, 0x2c, 0xc8, 0x49, 0x35, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x29, 0x28, 0x2e,
|
||||
0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2b, 0x49, 0x2d, 0x2e,
|
||||
0xd1, 0x83, 0x29, 0x52, 0x62, 0xe3, 0x62, 0xf1, 0x2d, 0x4e, 0x37, 0x34, 0x0a, 0xe3, 0x62, 0x09,
|
||||
0x2e, 0x4b, 0x36, 0x14, 0xf2, 0xe3, 0x62, 0x09, 0x4e, 0xcd, 0x4b, 0x11, 0x52, 0xd2, 0xc3, 0xa7,
|
||||
0x4d, 0x0f, 0xa4, 0x47, 0x8a, 0x08, 0x35, 0x4e, 0xdc, 0x51, 0x9c, 0xfa, 0x30, 0x91, 0x24, 0x36,
|
||||
0xb0, 0x8b, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x3d, 0x3e, 0x25, 0xa4, 0x00, 0x00,
|
||||
0x00,
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: multiple2.proto
|
||||
|
||||
// Multiple proto files in one package
|
||||
|
||||
package multiple
|
||||
|
||||
import (
|
||||
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 Msg2 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg2) Reset() {
|
||||
*x = Msg2{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_multiple2_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg2) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg2) ProtoMessage() {}
|
||||
|
||||
func (x *Msg2) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_multiple2_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 Msg2.ProtoReflect.Descriptor instead.
|
||||
func (*Msg2) Descriptor() ([]byte, []int) {
|
||||
return file_multiple2_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_multiple2_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_multiple2_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x1c, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x1a,
|
||||
0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x06, 0x0a, 0x04, 0x4d, 0x73, 0x67, 0x32, 0x32, 0xb8, 0x01, 0x0a, 0x04, 0x53, 0x76, 0x63,
|
||||
0x32, 0x12, 0x4e, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x22, 0x2e, 0x70, 0x73, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e,
|
||||
0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x32, 0x1a, 0x22, 0x2e,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67,
|
||||
0x32, 0x12, 0x60, 0x0a, 0x16, 0x53, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x2e, 0x70, 0x73,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x31, 0x1a,
|
||||
0x22, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x2e, 0x4d,
|
||||
0x73, 0x67, 0x31, 0x42, 0x0b, 0x5a, 0x09, 0x2f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_multiple2_proto_rawDescOnce sync.Once
|
||||
file_multiple2_proto_rawDescData = file_multiple2_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_multiple2_proto_rawDescGZIP() []byte {
|
||||
file_multiple2_proto_rawDescOnce.Do(func() {
|
||||
file_multiple2_proto_rawDescData = protoimpl.X.CompressGZIP(file_multiple2_proto_rawDescData)
|
||||
})
|
||||
return file_multiple2_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_multiple2_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_multiple2_proto_goTypes = []interface{}{
|
||||
(*Msg2)(nil), // 0: psrpc.internal.test.multiple.Msg2
|
||||
(*Msg1)(nil), // 1: psrpc.internal.test.multiple.Msg1
|
||||
}
|
||||
var file_multiple2_proto_depIdxs = []int32{
|
||||
0, // 0: psrpc.internal.test.multiple.Svc2.Send:input_type -> psrpc.internal.test.multiple.Msg2
|
||||
1, // 1: psrpc.internal.test.multiple.Svc2.SamePackageProtoImport:input_type -> psrpc.internal.test.multiple.Msg1
|
||||
0, // 2: psrpc.internal.test.multiple.Svc2.Send:output_type -> psrpc.internal.test.multiple.Msg2
|
||||
1, // 3: psrpc.internal.test.multiple.Svc2.SamePackageProtoImport:output_type -> psrpc.internal.test.multiple.Msg1
|
||||
2, // [2:4] is the sub-list for method output_type
|
||||
0, // [0:2] 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_multiple2_proto_init() }
|
||||
func file_multiple2_proto_init() {
|
||||
if File_multiple2_proto != nil {
|
||||
return
|
||||
}
|
||||
file_multiple1_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_multiple2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg2); 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_multiple2_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_multiple2_proto_goTypes,
|
||||
DependencyIndexes: file_multiple2_proto_depIdxs,
|
||||
MessageInfos: file_multiple2_proto_msgTypes,
|
||||
}.Build()
|
||||
File_multiple2_proto = out.File
|
||||
file_multiple2_proto_rawDesc = nil
|
||||
file_multiple2_proto_goTypes = nil
|
||||
file_multiple2_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Multiple proto files in one package
|
||||
package psrpc.internal.test.multiple;
|
||||
option go_package = "/multiple";
|
||||
|
||||
import "multiple1.proto";
|
||||
|
||||
message Msg2 {}
|
||||
|
||||
service Svc2 {
|
||||
rpc Send(Msg2) returns (Msg2);
|
||||
rpc SamePackageProtoImport(Msg1) returns (Msg1);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: multiple2.proto
|
||||
|
||||
// Multiple proto files in one package
|
||||
|
||||
package multiple
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// =====================
|
||||
// Svc2 Client Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Client interface {
|
||||
Send(context.Context, *Msg2, ...psrpc.RequestOpt) (*Msg2, error)
|
||||
|
||||
SamePackageProtoImport(context.Context, *Msg1, ...psrpc.RequestOpt) (*Msg1, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Svc2 ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type Svc2ServerImpl interface {
|
||||
Send(context.Context, *Msg2) (*Msg2, error)
|
||||
|
||||
SamePackageProtoImport(context.Context, *Msg1) (*Msg1, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Svc2 Server Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Server interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Client
|
||||
// ===========
|
||||
|
||||
type svc2Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvc2Client creates a psrpc client that implements the Svc2Client interface.
|
||||
func NewSvc2Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (Svc2Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc2", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svc2Client) Send(ctx context.Context, req *Msg2, opts ...psrpc.RequestOpt) (*Msg2, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg2](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
func (c *svc2Client) SamePackageProtoImport(ctx context.Context, req *Msg1, opts ...psrpc.RequestOpt) (*Msg1, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg1](ctx, c.client, "SamePackageProtoImport", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Server
|
||||
// ===========
|
||||
|
||||
type svc2Server struct {
|
||||
svc Svc2ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvc2Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvc2Server(serverID string, svc Svc2ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (Svc2Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc2", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("SamePackageProtoImport", svc.SamePackageProtoImport))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor1 = []byte{
|
||||
// 151 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcf, 0x2d, 0xcd, 0x29,
|
||||
0xc9, 0x2c, 0xc8, 0x49, 0x35, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x29, 0x28, 0x2e,
|
||||
0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2b, 0x49, 0x2d, 0x2e,
|
||||
0xd1, 0x83, 0x29, 0x92, 0x82, 0x2b, 0x37, 0x84, 0x28, 0x57, 0x62, 0xe3, 0x62, 0xf1, 0x2d, 0x4e,
|
||||
0x37, 0x32, 0xda, 0xc1, 0xc8, 0xc5, 0x12, 0x5c, 0x96, 0x6c, 0x24, 0xe4, 0xc7, 0xc5, 0x12, 0x9c,
|
||||
0x9a, 0x97, 0x22, 0xa4, 0xa4, 0x87, 0xcf, 0x20, 0x3d, 0x90, 0x26, 0x29, 0x22, 0xd4, 0x08, 0x25,
|
||||
0x70, 0x89, 0x05, 0x27, 0xe6, 0xa6, 0x06, 0x24, 0x26, 0x67, 0x27, 0xa6, 0xa7, 0x06, 0x80, 0x2c,
|
||||
0xf5, 0xcc, 0x2d, 0xc8, 0x2f, 0x2a, 0x21, 0xc2, 0x06, 0x43, 0x22, 0x6c, 0x30, 0x74, 0xe2, 0x8e,
|
||||
0xe2, 0xd4, 0x87, 0x89, 0x24, 0xb1, 0x81, 0xbd, 0x65, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x06,
|
||||
0x9e, 0x42, 0x70, 0x18, 0x01, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package multiple
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package my_service
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package my_service
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. -I ../../../protoc-gen-psrpc/options -I=. my_service.proto
|
||||
@@ -0,0 +1,347 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: my_service.proto
|
||||
|
||||
package my_service
|
||||
|
||||
import (
|
||||
_ "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 Ignored struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Ignored) Reset() {
|
||||
*x = Ignored{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_my_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Ignored) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Ignored) ProtoMessage() {}
|
||||
|
||||
func (x *Ignored) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_my_service_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 Ignored.ProtoReflect.Descriptor instead.
|
||||
func (*Ignored) Descriptor() ([]byte, []int) {
|
||||
return file_my_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type MyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *MyRequest) Reset() {
|
||||
*x = MyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_my_service_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MyRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *MyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_my_service_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 MyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*MyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_my_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type MyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *MyResponse) Reset() {
|
||||
*x = MyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_my_service_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MyResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *MyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_my_service_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 MyResponse.ProtoReflect.Descriptor instead.
|
||||
func (*MyResponse) Descriptor() ([]byte, []int) {
|
||||
return file_my_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type MyUpdate struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *MyUpdate) Reset() {
|
||||
*x = MyUpdate{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_my_service_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MyUpdate) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MyUpdate) ProtoMessage() {}
|
||||
|
||||
func (x *MyUpdate) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_my_service_proto_msgTypes[3]
|
||||
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 MyUpdate.ProtoReflect.Descriptor instead.
|
||||
func (*MyUpdate) Descriptor() ([]byte, []int) {
|
||||
return file_my_service_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
var File_my_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_my_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x6d, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x21, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x09, 0x0a, 0x07, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x22,
|
||||
0x0b, 0x0a, 0x09, 0x4d, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a,
|
||||
0x4d, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0a, 0x0a, 0x08, 0x4d, 0x79,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x32, 0xcd, 0x05, 0x0a, 0x09, 0x4d, 0x79, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x52, 0x50,
|
||||
0x43, 0x12, 0x2c, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2d, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73,
|
||||
0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x52, 0x50, 0x43, 0x12, 0x2c,
|
||||
0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70,
|
||||
0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65,
|
||||
0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x2e, 0x4d, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xb2, 0x89, 0x01,
|
||||
0x02, 0x20, 0x01, 0x12, 0x6f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12,
|
||||
0x2c, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0xb2, 0x89,
|
||||
0x01, 0x02, 0x08, 0x01, 0x12, 0x7b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f,
|
||||
0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73,
|
||||
0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f,
|
||||
0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x0c, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01, 0xb2, 0x89, 0x01, 0x02, 0x08,
|
||||
0x01, 0x12, 0x70, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x1a, 0x2b,
|
||||
0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x2e, 0x4d, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x06, 0xb2, 0x89, 0x01,
|
||||
0x02, 0x10, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
|
||||
0x67, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x73, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e,
|
||||
0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x67,
|
||||
0x6e, 0x6f, 0x72, 0x65, 0x64, 0x1a, 0x2b, 0x2e, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74,
|
||||
0x6f, 0x6d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x79, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x22, 0x12, 0xb2, 0x89, 0x01, 0x02, 0x10, 0x01, 0xb2, 0x89, 0x01, 0x02, 0x18, 0x01,
|
||||
0xb2, 0x89, 0x01, 0x02, 0x08, 0x01, 0x42, 0x0d, 0x5a, 0x0b, 0x2f, 0x6d, 0x79, 0x5f, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_my_service_proto_rawDescOnce sync.Once
|
||||
file_my_service_proto_rawDescData = file_my_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_my_service_proto_rawDescGZIP() []byte {
|
||||
file_my_service_proto_rawDescOnce.Do(func() {
|
||||
file_my_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_my_service_proto_rawDescData)
|
||||
})
|
||||
return file_my_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_my_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_my_service_proto_goTypes = []interface{}{
|
||||
(*Ignored)(nil), // 0: psrpc.internal.test.customservice.Ignored
|
||||
(*MyRequest)(nil), // 1: psrpc.internal.test.customservice.MyRequest
|
||||
(*MyResponse)(nil), // 2: psrpc.internal.test.customservice.MyResponse
|
||||
(*MyUpdate)(nil), // 3: psrpc.internal.test.customservice.MyUpdate
|
||||
}
|
||||
var file_my_service_proto_depIdxs = []int32{
|
||||
1, // 0: psrpc.internal.test.customservice.MyService.NormalRPC:input_type -> psrpc.internal.test.customservice.MyRequest
|
||||
1, // 1: psrpc.internal.test.customservice.MyService.IntensiveRPC:input_type -> psrpc.internal.test.customservice.MyRequest
|
||||
1, // 2: psrpc.internal.test.customservice.MyService.GetStats:input_type -> psrpc.internal.test.customservice.MyRequest
|
||||
1, // 3: psrpc.internal.test.customservice.MyService.GetRegionStats:input_type -> psrpc.internal.test.customservice.MyRequest
|
||||
0, // 4: psrpc.internal.test.customservice.MyService.ProcessUpdate:input_type -> psrpc.internal.test.customservice.Ignored
|
||||
0, // 5: psrpc.internal.test.customservice.MyService.UpdateRegionState:input_type -> psrpc.internal.test.customservice.Ignored
|
||||
2, // 6: psrpc.internal.test.customservice.MyService.NormalRPC:output_type -> psrpc.internal.test.customservice.MyResponse
|
||||
2, // 7: psrpc.internal.test.customservice.MyService.IntensiveRPC:output_type -> psrpc.internal.test.customservice.MyResponse
|
||||
2, // 8: psrpc.internal.test.customservice.MyService.GetStats:output_type -> psrpc.internal.test.customservice.MyResponse
|
||||
2, // 9: psrpc.internal.test.customservice.MyService.GetRegionStats:output_type -> psrpc.internal.test.customservice.MyResponse
|
||||
3, // 10: psrpc.internal.test.customservice.MyService.ProcessUpdate:output_type -> psrpc.internal.test.customservice.MyUpdate
|
||||
3, // 11: psrpc.internal.test.customservice.MyService.UpdateRegionState:output_type -> psrpc.internal.test.customservice.MyUpdate
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] 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_my_service_proto_init() }
|
||||
func file_my_service_proto_init() {
|
||||
if File_my_service_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_my_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Ignored); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_my_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_my_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_my_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MyUpdate); 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_my_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_my_service_proto_goTypes,
|
||||
DependencyIndexes: file_my_service_proto_depIdxs,
|
||||
MessageInfos: file_my_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_my_service_proto = out.File
|
||||
file_my_service_proto_rawDesc = nil
|
||||
file_my_service_proto_goTypes = nil
|
||||
file_my_service_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc.internal.test.customservice;
|
||||
|
||||
import "options.proto";
|
||||
|
||||
// Test to make sure that a service with no methods doesn't break.
|
||||
option go_package = "/my_service";
|
||||
|
||||
service MyService {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
rpc NormalRPC(MyRequest) returns (MyResponse);
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
rpc IntensiveRPC(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).affinity_func = true;
|
||||
};
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
rpc GetStats(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).multi = true;
|
||||
};
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
rpc GetRegionStats(MyRequest) returns (MyResponse) {
|
||||
option (psrpc.options).topics = true;
|
||||
option (psrpc.options).multi = true;
|
||||
}
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
rpc ProcessUpdate(Ignored) returns (MyUpdate) {
|
||||
option (psrpc.options).subscription = true;
|
||||
};
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
rpc UpdateRegionState(Ignored) returns (MyUpdate) {
|
||||
option (psrpc.options).subscription = true;
|
||||
option (psrpc.options).topics = true;
|
||||
option (psrpc.options).multi = true;
|
||||
}
|
||||
}
|
||||
|
||||
message Ignored {}
|
||||
message MyRequest {}
|
||||
message MyResponse {}
|
||||
message MyUpdate {}
|
||||
@@ -0,0 +1,192 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: my_service.proto
|
||||
|
||||
package my_service
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc1 "github.com/livekit/psrpc"
|
||||
|
||||
// ==========================
|
||||
// MyService Client Interface
|
||||
// ==========================
|
||||
|
||||
type MyServiceClient interface {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
NormalRPC(context.Context, *MyRequest, ...psrpc1.RequestOpt) (*MyResponse, error)
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
IntensiveRPC(context.Context, *MyRequest, ...psrpc1.RequestOpt) (*MyResponse, error)
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
GetStats(context.Context, *MyRequest, ...psrpc1.RequestOpt) (<-chan *psrpc1.Response[*MyResponse], error)
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
GetRegionStats(context.Context, string, *MyRequest, ...psrpc1.RequestOpt) (<-chan *psrpc1.Response[*MyResponse], error)
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
SubscribeProcessUpdate(context.Context) (psrpc1.Subscription[*MyUpdate], error)
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
SubscribeUpdateRegionState(context.Context, string) (psrpc1.Subscription[*MyUpdate], error)
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// MyService ServerImpl Interface
|
||||
// ==============================
|
||||
|
||||
type MyServiceServerImpl interface {
|
||||
// A normal RPC - one request, one response. The request will be handled by the first available server
|
||||
NormalRPC(context.Context, *MyRequest) (*MyResponse, error)
|
||||
|
||||
// An RPC with a server affinity function for handler selection.
|
||||
IntensiveRPC(context.Context, *MyRequest) (*MyResponse, error)
|
||||
IntensiveRPCAffinity(*MyRequest) float32
|
||||
|
||||
// A multi-rpc - a client will send one request, and receive one response each from every server
|
||||
GetStats(context.Context, *MyRequest) (*MyResponse, error)
|
||||
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
GetRegionStats(context.Context, *MyRequest) (*MyResponse, error)
|
||||
}
|
||||
|
||||
// ==========================
|
||||
// MyService Server Interface
|
||||
// ==========================
|
||||
|
||||
type MyServiceServer interface {
|
||||
// An RPC with topics - a client can send one request, and receive one response from each server in one region
|
||||
RegisterGetRegionStatsTopic(string) error
|
||||
DeregisterGetRegionStatsTopic(string) error
|
||||
|
||||
// A queue subscription - even if multiple clients are subscribed, only one will receive this update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
PublishProcessUpdate(context.Context, *MyUpdate) error
|
||||
|
||||
// A subscription with topics - every client subscribed to the topic will receive every update.
|
||||
// The request parameter (Ignored) will be ignored when generating go files.
|
||||
PublishUpdateRegionState(context.Context, string, *MyUpdate) error
|
||||
}
|
||||
|
||||
// ================
|
||||
// MyService Client
|
||||
// ================
|
||||
|
||||
type myServiceClient struct {
|
||||
client psrpc1.RPCClient
|
||||
}
|
||||
|
||||
// NewMyServiceClient creates a psrpc client that implements the MyServiceClient interface.
|
||||
func NewMyServiceClient(clientID string, bus psrpc1.MessageBus, opts ...psrpc1.ClientOpt) (MyServiceClient, error) {
|
||||
rpcClient, err := psrpc1.NewRPCClient("MyService", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &myServiceClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *myServiceClient) NormalRPC(ctx context.Context, req *MyRequest, opts ...psrpc1.RequestOpt) (*MyResponse, error) {
|
||||
return psrpc1.RequestTopicSingle[*MyResponse](ctx, c.client, "NormalRPC", "", req, opts...)
|
||||
}
|
||||
|
||||
func (c *myServiceClient) IntensiveRPC(ctx context.Context, req *MyRequest, opts ...psrpc1.RequestOpt) (*MyResponse, error) {
|
||||
return psrpc1.RequestTopicSingle[*MyResponse](ctx, c.client, "IntensiveRPC", "", req, opts...)
|
||||
}
|
||||
|
||||
func (c *myServiceClient) GetStats(ctx context.Context, req *MyRequest, opts ...psrpc1.RequestOpt) (<-chan *psrpc1.Response[*MyResponse], error) {
|
||||
return psrpc1.RequestTopicAll[*MyResponse](ctx, c.client, "GetStats", "", req, opts...)
|
||||
}
|
||||
|
||||
func (c *myServiceClient) GetRegionStats(ctx context.Context, topic string, req *MyRequest, opts ...psrpc1.RequestOpt) (<-chan *psrpc1.Response[*MyResponse], error) {
|
||||
return psrpc1.RequestTopicAll[*MyResponse](ctx, c.client, "GetRegionStats", topic, req, opts...)
|
||||
}
|
||||
|
||||
func (c *myServiceClient) SubscribeProcessUpdate(ctx context.Context) (psrpc1.Subscription[*MyUpdate], error) {
|
||||
return psrpc1.SubscribeTopicQueue[*MyUpdate](ctx, c.client, "ProcessUpdate", "")
|
||||
}
|
||||
|
||||
func (c *myServiceClient) SubscribeUpdateRegionState(ctx context.Context, topic string) (psrpc1.Subscription[*MyUpdate], error) {
|
||||
return psrpc1.SubscribeTopic[*MyUpdate](ctx, c.client, "UpdateRegionState", topic)
|
||||
}
|
||||
|
||||
// ================
|
||||
// MyService Server
|
||||
// ================
|
||||
|
||||
type myServiceServer struct {
|
||||
svc MyServiceServerImpl
|
||||
rpc psrpc1.RPCServer
|
||||
}
|
||||
|
||||
// NewMyServiceServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewMyServiceServer(serverID string, svc MyServiceServerImpl, bus psrpc1.MessageBus, opts ...psrpc1.ServerOpt) (MyServiceServer, error) {
|
||||
rpcServer := psrpc1.NewRPCServer("MyService", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc1.NewHandler("NormalRPC", svc.NormalRPC))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = rpcServer.RegisterHandler(psrpc1.NewHandlerWithAffinity("IntensiveRPC", svc.IntensiveRPC, svc.IntensiveRPCAffinity))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = rpcServer.RegisterHandler(psrpc1.NewHandler("GetStats", svc.GetStats))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &myServiceServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *myServiceServer) RegisterGetRegionStatsTopic(topic string) error {
|
||||
return s.rpc.RegisterHandler(psrpc1.NewTopicHandler("GetRegionStats", topic, s.svc.GetRegionStats))
|
||||
}
|
||||
|
||||
func (s *myServiceServer) DeregisterGetRegionStatsTopic(topic string) error {
|
||||
return s.rpc.DeregisterTopic("GetRegionStats", topic)
|
||||
}
|
||||
|
||||
func (s *myServiceServer) PublishProcessUpdate(ctx context.Context, msg *MyUpdate) error {
|
||||
return s.rpc.PublishTopic(ctx, "ProcessUpdate", "", msg)
|
||||
}
|
||||
|
||||
func (s *myServiceServer) PublishUpdateRegionState(ctx context.Context, topic string, msg *MyUpdate) error {
|
||||
return s.rpc.PublishTopic(ctx, "UpdateRegionState", topic, msg)
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 288 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0x4f, 0x4e, 0xf3, 0x30,
|
||||
0x10, 0xc5, 0xe5, 0x4f, 0x1f, 0xc5, 0x9d, 0xb6, 0x28, 0x78, 0x55, 0x65, 0x05, 0x59, 0xf2, 0xc7,
|
||||
0x48, 0x70, 0x03, 0x58, 0x54, 0x5d, 0x14, 0x55, 0xa9, 0xd8, 0xb0, 0x41, 0x21, 0x1d, 0x95, 0x48,
|
||||
0x8d, 0x6d, 0x3c, 0xd3, 0x42, 0x8e, 0x90, 0xeb, 0xe4, 0x04, 0x1c, 0x0d, 0x15, 0x57, 0x74, 0x49,
|
||||
0x36, 0xed, 0xd2, 0xd6, 0xf3, 0xfb, 0xf9, 0x69, 0xe6, 0x41, 0x54, 0x56, 0x2f, 0x84, 0x7e, 0x5d,
|
||||
0xe4, 0xa8, 0x9d, 0xb7, 0x6c, 0xd5, 0xb9, 0x23, 0xef, 0x72, 0x5d, 0x18, 0x46, 0x6f, 0xb2, 0xa5,
|
||||
0x66, 0x24, 0xd6, 0xf9, 0x8a, 0xd8, 0x96, 0x5b, 0x61, 0x3c, 0xb0, 0x8e, 0x0b, 0x6b, 0x28, 0xbc,
|
||||
0x48, 0xba, 0x70, 0x3c, 0x5e, 0x18, 0xeb, 0x71, 0x9e, 0xf4, 0xa0, 0x3b, 0xa9, 0x52, 0x7c, 0x5f,
|
||||
0x21, 0x71, 0xd2, 0x07, 0xd8, 0x1c, 0xc8, 0x59, 0x43, 0x98, 0x00, 0xc8, 0x49, 0xf5, 0xe4, 0xe6,
|
||||
0x19, 0xe3, 0xed, 0xd7, 0xd1, 0x46, 0x37, 0x0b, 0x76, 0xea, 0x0d, 0xba, 0x8f, 0xd6, 0x97, 0xd9,
|
||||
0x32, 0x9d, 0x3e, 0xa8, 0x2b, 0xfd, 0x27, 0x5f, 0xff, 0x22, 0xe2, 0xeb, 0x96, 0xea, 0xf0, 0x07,
|
||||
0x45, 0xd0, 0x1f, 0x1b, 0x46, 0x43, 0xc5, 0x1a, 0xf7, 0x0d, 0x4b, 0x3a, 0x4d, 0x2d, 0xfe, 0x9d,
|
||||
0x09, 0x65, 0x41, 0x8e, 0x90, 0x67, 0x9c, 0x31, 0x1d, 0x00, 0x28, 0x85, 0xfa, 0x80, 0x93, 0x11,
|
||||
0x72, 0x8a, 0x8b, 0xc2, 0x9a, 0x03, 0x60, 0x65, 0x53, 0x8b, 0xff, 0x52, 0x0c, 0x85, 0x72, 0x30,
|
||||
0x98, 0x7a, 0x9b, 0x23, 0x51, 0x98, 0xb3, 0xba, 0x68, 0xe1, 0xb4, 0x5d, 0x9d, 0xf8, 0xb2, 0x15,
|
||||
0x35, 0x18, 0x87, 0xa8, 0x91, 0x50, 0x9f, 0x70, 0x1a, 0x6e, 0x76, 0x69, 0xf7, 0x48, 0x85, 0xa6,
|
||||
0x16, 0x1d, 0x29, 0x22, 0x31, 0x14, 0xf7, 0x83, 0xe7, 0xde, 0xcd, 0xae, 0x3b, 0xaf, 0x9d, 0x9f,
|
||||
0x2a, 0xdc, 0x7d, 0x07, 0x00, 0x00, 0xff, 0xff, 0xee, 0x5b, 0x87, 0x9b, 0x50, 0x03, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package no_package_name
|
||||
|
||||
//go:generate protoc --go_out=module=github.com/livekit/psrpc/internal/test/no_package_name:. --psrpc_out=module=github.com/livekit/psrpc/internal/test/no_package_name:. no_package_name.proto
|
||||
@@ -0,0 +1,137 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: no_package_name.proto
|
||||
|
||||
package no_package_name
|
||||
|
||||
import (
|
||||
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 Msg struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg) Reset() {
|
||||
*x = Msg{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_no_package_name_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_no_package_name_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 Msg.ProtoReflect.Descriptor instead.
|
||||
func (*Msg) Descriptor() ([]byte, []int) {
|
||||
return file_no_package_name_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_no_package_name_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_no_package_name_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x05, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x32, 0x19,
|
||||
0x0a, 0x03, 0x53, 0x76, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x04, 0x2e,
|
||||
0x4d, 0x73, 0x67, 0x1a, 0x04, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2f, 0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_no_package_name_proto_rawDescOnce sync.Once
|
||||
file_no_package_name_proto_rawDescData = file_no_package_name_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_no_package_name_proto_rawDescGZIP() []byte {
|
||||
file_no_package_name_proto_rawDescOnce.Do(func() {
|
||||
file_no_package_name_proto_rawDescData = protoimpl.X.CompressGZIP(file_no_package_name_proto_rawDescData)
|
||||
})
|
||||
return file_no_package_name_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_no_package_name_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_no_package_name_proto_goTypes = []interface{}{
|
||||
(*Msg)(nil), // 0: Msg
|
||||
}
|
||||
var file_no_package_name_proto_depIdxs = []int32{
|
||||
0, // 0: Svc.Send:input_type -> Msg
|
||||
0, // 1: Svc.Send:output_type -> Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_no_package_name_proto_init() }
|
||||
func file_no_package_name_proto_init() {
|
||||
if File_no_package_name_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_no_package_name_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg); 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_no_package_name_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_no_package_name_proto_goTypes,
|
||||
DependencyIndexes: file_no_package_name_proto_depIdxs,
|
||||
MessageInfos: file_no_package_name_proto_msgTypes,
|
||||
}.Build()
|
||||
File_no_package_name_proto = out.File
|
||||
file_no_package_name_proto_rawDesc = nil
|
||||
file_no_package_name_proto_goTypes = nil
|
||||
file_no_package_name_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// No package name
|
||||
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/no_package_name";
|
||||
|
||||
message Msg {}
|
||||
|
||||
service Svc {
|
||||
rpc Send(Msg) returns(Msg);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: no_package_name.proto
|
||||
|
||||
package no_package_name
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// ====================
|
||||
// Svc Client Interface
|
||||
// ====================
|
||||
|
||||
type SvcClient interface {
|
||||
Send(context.Context, *Msg, ...psrpc.RequestOpt) (*Msg, error)
|
||||
}
|
||||
|
||||
// ========================
|
||||
// Svc ServerImpl Interface
|
||||
// ========================
|
||||
|
||||
type SvcServerImpl interface {
|
||||
Send(context.Context, *Msg) (*Msg, error)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// Svc Server Interface
|
||||
// ====================
|
||||
|
||||
type SvcServer interface {
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Client
|
||||
// ==========
|
||||
|
||||
type svcClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvcClient creates a psrpc client that implements the SvcClient interface.
|
||||
func NewSvcClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (SvcClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svcClient) Send(ctx context.Context, req *Msg, opts ...psrpc.RequestOpt) (*Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg](ctx, c.client, "Send", "", req, opts...)
|
||||
}
|
||||
|
||||
// ==========
|
||||
// Svc Server
|
||||
// ==========
|
||||
|
||||
type svcServer struct {
|
||||
svc SvcServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvcServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvcServer(serverID string, svc SvcServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (SvcServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Send", svc.Send))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svcServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 128 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0xcb, 0x8f, 0x2f,
|
||||
0x48, 0x4c, 0xce, 0x4e, 0x4c, 0x4f, 0x8d, 0xcf, 0x4b, 0xcc, 0x4d, 0xd5, 0x2b, 0x28, 0xca, 0x2f,
|
||||
0xc9, 0x57, 0x62, 0xe5, 0x62, 0xf6, 0x2d, 0x4e, 0x37, 0x92, 0xe4, 0x62, 0x0e, 0x2e, 0x4b, 0x16,
|
||||
0x12, 0xe2, 0x62, 0x09, 0x4e, 0xcd, 0x4b, 0x11, 0x62, 0xd1, 0xf3, 0x2d, 0x4e, 0x97, 0x02, 0x93,
|
||||
0x4e, 0x16, 0x51, 0x66, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x39,
|
||||
0x99, 0x65, 0xa9, 0xd9, 0x99, 0x25, 0xfa, 0x05, 0xc5, 0x45, 0x05, 0xc9, 0xfa, 0x99, 0x79, 0x25,
|
||||
0xa9, 0x45, 0x79, 0x89, 0x39, 0xfa, 0x25, 0xa9, 0xc5, 0x25, 0xfa, 0x68, 0x36, 0x24, 0xb1, 0x81,
|
||||
0xad, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x79, 0xb2, 0x2e, 0x0a, 0x7b, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package no_package_name_importer
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package no_package_name_importer
|
||||
|
||||
//go:generate protoc --proto_path=../ --go_out=module=github.com/livekit/psrpc/internal/test:../ --psrpc_out=module=github.com/livekit/psrpc/internal/test:../ ../no_package_name_importer/no_package_name_importer.proto
|
||||
@@ -0,0 +1,76 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: no_package_name_importer/no_package_name_importer.proto
|
||||
|
||||
package no_package_name_importer
|
||||
|
||||
import (
|
||||
no_package_name "github.com/livekit/psrpc/internal/test/no_package_name"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_no_package_name_importer_no_package_name_importer_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_no_package_name_importer_no_package_name_importer_proto_rawDesc = []byte{
|
||||
0x0a, 0x37, 0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2f, 0x6e, 0x6f, 0x5f, 0x70, 0x61,
|
||||
0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x6e, 0x6f, 0x5f, 0x70, 0x61,
|
||||
0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x6e, 0x6f, 0x5f, 0x70, 0x61,
|
||||
0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x32, 0x1c, 0x0a, 0x04, 0x53, 0x76, 0x63, 0x32, 0x12, 0x14, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68,
|
||||
0x6f, 0x64, 0x12, 0x04, 0x2e, 0x4d, 0x73, 0x67, 0x1a, 0x04, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x41,
|
||||
0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76,
|
||||
0x65, 0x6b, 0x69, 0x74, 0x2f, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b,
|
||||
0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65,
|
||||
0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_no_package_name_importer_no_package_name_importer_proto_goTypes = []interface{}{
|
||||
(*no_package_name.Msg)(nil), // 0: Msg
|
||||
}
|
||||
var file_no_package_name_importer_no_package_name_importer_proto_depIdxs = []int32{
|
||||
0, // 0: Svc2.Method:input_type -> Msg
|
||||
0, // 1: Svc2.Method:output_type -> Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_no_package_name_importer_no_package_name_importer_proto_init() }
|
||||
func file_no_package_name_importer_no_package_name_importer_proto_init() {
|
||||
if File_no_package_name_importer_no_package_name_importer_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_no_package_name_importer_no_package_name_importer_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_no_package_name_importer_no_package_name_importer_proto_goTypes,
|
||||
DependencyIndexes: file_no_package_name_importer_no_package_name_importer_proto_depIdxs,
|
||||
}.Build()
|
||||
File_no_package_name_importer_no_package_name_importer_proto = out.File
|
||||
file_no_package_name_importer_no_package_name_importer_proto_rawDesc = nil
|
||||
file_no_package_name_importer_no_package_name_importer_proto_goTypes = nil
|
||||
file_no_package_name_importer_no_package_name_importer_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Import another proto file that doesn't have a package name
|
||||
|
||||
import "no_package_name/no_package_name.proto"; // import is relative to protoc's option --proto_path
|
||||
|
||||
option go_package = "github.com/livekit/psrpc/internal/test/no_package_name_importer";
|
||||
|
||||
service Svc2 {
|
||||
rpc Method(Msg) returns (Msg);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: no_package_name_importer/no_package_name_importer.proto
|
||||
|
||||
package no_package_name_importer
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
import no_package_name "github.com/livekit/psrpc/internal/test/no_package_name"
|
||||
|
||||
// =====================
|
||||
// Svc2 Client Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Client interface {
|
||||
Method(context.Context, *no_package_name.Msg, ...psrpc.RequestOpt) (*no_package_name.Msg, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Svc2 ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type Svc2ServerImpl interface {
|
||||
Method(context.Context, *no_package_name.Msg) (*no_package_name.Msg, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Svc2 Server Interface
|
||||
// =====================
|
||||
|
||||
type Svc2Server interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Client
|
||||
// ===========
|
||||
|
||||
type svc2Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewSvc2Client creates a psrpc client that implements the Svc2Client interface.
|
||||
func NewSvc2Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (Svc2Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Svc2", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *svc2Client) Method(ctx context.Context, req *no_package_name.Msg, opts ...psrpc.RequestOpt) (*no_package_name.Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*no_package_name.Msg](ctx, c.client, "Method", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Svc2 Server
|
||||
// ===========
|
||||
|
||||
type svc2Server struct {
|
||||
svc Svc2ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewSvc2Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewSvc2Server(serverID string, svc Svc2ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (Svc2Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Svc2", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Method", svc.Method))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &svc2Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 144 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xcf, 0xcb, 0x8f, 0x2f,
|
||||
0x48, 0x4c, 0xce, 0x4e, 0x4c, 0x4f, 0x8d, 0xcf, 0x4b, 0xcc, 0x4d, 0x8d, 0xcf, 0xcc, 0x2d, 0xc8,
|
||||
0x2f, 0x2a, 0x49, 0x2d, 0xd2, 0xc7, 0x25, 0xa1, 0x57, 0x50, 0x94, 0x5f, 0x92, 0x2f, 0xa5, 0x8a,
|
||||
0x26, 0x8f, 0xae, 0x1e, 0xa2, 0xcc, 0x48, 0x86, 0x8b, 0x25, 0xb8, 0x2c, 0xd9, 0x48, 0x48, 0x84,
|
||||
0x8b, 0xcd, 0x37, 0xb5, 0x24, 0x23, 0x3f, 0x45, 0x88, 0x45, 0xcf, 0xb7, 0x38, 0x5d, 0x0a, 0x4c,
|
||||
0x3a, 0x39, 0x46, 0xd9, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe7,
|
||||
0x64, 0x96, 0xa5, 0x66, 0x67, 0x96, 0xe8, 0x17, 0x14, 0x17, 0x15, 0x24, 0xeb, 0x67, 0xe6, 0x95,
|
||||
0xa4, 0x16, 0xe5, 0x25, 0xe6, 0xe8, 0x97, 0xa4, 0x16, 0x97, 0xe0, 0x74, 0x4d, 0x12, 0x1b, 0xd8,
|
||||
0x1e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x62, 0x56, 0x40, 0xc9, 0x00, 0x00, 0x00,
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/lithammer/shortuuid/v3"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/livekit/psrpc"
|
||||
"github.com/livekit/psrpc/internal/test/my_service"
|
||||
)
|
||||
|
||||
func TestGeneratedService(t *testing.T) {
|
||||
rc := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"localhost:6379"}})
|
||||
bus := psrpc.NewRedisMessageBus(rc)
|
||||
|
||||
ctx := context.Background()
|
||||
req := &my_service.MyRequest{}
|
||||
update := &my_service.MyUpdate{}
|
||||
sA := createServer(t, bus)
|
||||
sB := createServer(t, bus)
|
||||
cA := createClient(t, bus)
|
||||
cB := createClient(t, bus)
|
||||
|
||||
// rpc NormalRPC(MyRequest) returns (MyResponse);
|
||||
_, err := cA.NormalRPC(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, sA.counts["NormalRPC"]+sB.counts["NormalRPC"])
|
||||
|
||||
// rpc IntensiveRPC(MyRequest) returns (MyResponse) {
|
||||
// option (psrpc.options).affinity_func = true;
|
||||
_, err = cB.IntensiveRPC(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, sA.counts["IntensiveRPC"]+sB.counts["IntensiveRPC"])
|
||||
require.Equal(t, 1, sA.counts["IntensiveRPCAffinity"])
|
||||
require.Equal(t, 1, sB.counts["IntensiveRPCAffinity"])
|
||||
|
||||
// rpc GetStats(MyRequest) returns (MyResponse) {
|
||||
// option (psrpc.options).multi = true;
|
||||
respChan, err := cA.GetStats(ctx, req)
|
||||
require.NoError(t, err)
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case res := <-respChan:
|
||||
require.NoError(t, res.Err)
|
||||
case <-time.After(time.Second * 3):
|
||||
t.Fatalf("timed out")
|
||||
}
|
||||
}
|
||||
require.Equal(t, 1, sA.counts["GetStats"])
|
||||
require.Equal(t, 1, sB.counts["GetStats"])
|
||||
|
||||
// rpc GetRegionStats(MyRequest) returns (MyResponse) {
|
||||
// option (psrpc.options).topics = true;
|
||||
// option (psrpc.options).multi = true;
|
||||
require.NoError(t, sA.server.RegisterGetRegionStatsTopic("regionA"))
|
||||
require.NoError(t, sA.server.RegisterGetRegionStatsTopic("regionB"))
|
||||
require.NoError(t, sA.server.DeregisterGetRegionStatsTopic("regionB"))
|
||||
require.NoError(t, sB.server.RegisterGetRegionStatsTopic("regionB"))
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
respChan, err = cB.GetRegionStats(ctx, "regionB", req)
|
||||
require.NoError(t, err)
|
||||
select {
|
||||
case res := <-respChan:
|
||||
require.NotNil(t, res)
|
||||
require.NoError(t, res.Err)
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("timed out")
|
||||
}
|
||||
require.Equal(t, 0, sA.counts["GetRegionStats"])
|
||||
require.Equal(t, 1, sB.counts["GetRegionStats"])
|
||||
|
||||
// rpc ProcessUpdate(Ignored) returns (MyUpdate) {
|
||||
// option (psrpc.options).subscription = true;
|
||||
subA, err := cA.SubscribeProcessUpdate(ctx)
|
||||
require.NoError(t, err)
|
||||
subB, err := cB.SubscribeProcessUpdate(ctx)
|
||||
require.NoError(t, err)
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
require.NoError(t, sA.server.PublishProcessUpdate(ctx, update))
|
||||
requireOne(t, subA, subB)
|
||||
require.NoError(t, subA.Close())
|
||||
require.NoError(t, subB.Close())
|
||||
|
||||
// rpc UpdateRegionState(Ignored) returns (MyUpdate) {
|
||||
// option (psrpc.options).subscription = true;
|
||||
// option (psrpc.options).topics = true;
|
||||
// option (psrpc.options).multi = true;
|
||||
subA, err = cA.SubscribeUpdateRegionState(ctx, "regionA")
|
||||
require.NoError(t, err)
|
||||
subB, err = cB.SubscribeUpdateRegionState(ctx, "regionA")
|
||||
require.NoError(t, err)
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
require.NoError(t, sB.server.PublishUpdateRegionState(ctx, "regionA", update))
|
||||
requireTwo(t, subA, subB)
|
||||
require.NoError(t, subA.Close())
|
||||
require.NoError(t, subB.Close())
|
||||
}
|
||||
|
||||
func requireOne(t *testing.T, subA, subB psrpc.Subscription[*my_service.MyUpdate]) {
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case <-subA.Channel():
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
case <-subB.Channel():
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
if i == 1 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
t.Fatalf("%d responses received", i*2)
|
||||
}
|
||||
}
|
||||
|
||||
func requireTwo(t *testing.T, subA, subB psrpc.Subscription[*my_service.MyUpdate]) {
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case <-subA.Channel():
|
||||
case <-subB.Channel():
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("timed out")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createServer(t *testing.T, bus psrpc.MessageBus) *MyService {
|
||||
svc := &MyService{
|
||||
counts: make(map[string]int),
|
||||
}
|
||||
server, err := my_service.NewMyServiceServer(newID(), svc, bus)
|
||||
require.NoError(t, err)
|
||||
svc.server = server
|
||||
return svc
|
||||
}
|
||||
|
||||
func createClient(t *testing.T, bus psrpc.MessageBus) my_service.MyServiceClient {
|
||||
client, err := my_service.NewMyServiceClient(newID(), bus)
|
||||
require.NoError(t, err)
|
||||
return client
|
||||
}
|
||||
|
||||
type MyService struct {
|
||||
sync.Mutex
|
||||
|
||||
server my_service.MyServiceServer
|
||||
counts map[string]int
|
||||
}
|
||||
|
||||
func (s *MyService) NormalRPC(ctx context.Context, req *my_service.MyRequest) (*my_service.MyResponse, error) {
|
||||
s.Lock()
|
||||
s.counts["NormalRPC"]++
|
||||
s.Unlock()
|
||||
return &my_service.MyResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *MyService) IntensiveRPC(ctx context.Context, req *my_service.MyRequest) (*my_service.MyResponse, error) {
|
||||
s.Lock()
|
||||
s.counts["IntensiveRPC"]++
|
||||
s.Unlock()
|
||||
return &my_service.MyResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *MyService) IntensiveRPCAffinity(req *my_service.MyRequest) float32 {
|
||||
s.Lock()
|
||||
s.counts["IntensiveRPCAffinity"]++
|
||||
s.Unlock()
|
||||
return rand.Float32()
|
||||
}
|
||||
|
||||
func (s *MyService) GetStats(ctx context.Context, req *my_service.MyRequest) (*my_service.MyResponse, error) {
|
||||
s.Lock()
|
||||
s.counts["GetStats"]++
|
||||
s.Unlock()
|
||||
return &my_service.MyResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *MyService) GetRegionStats(ctx context.Context, req *my_service.MyRequest) (*my_service.MyResponse, error) {
|
||||
s.Lock()
|
||||
s.counts["GetRegionStats"]++
|
||||
s.Unlock()
|
||||
return &my_service.MyResponse{}, nil
|
||||
}
|
||||
|
||||
func newID() string {
|
||||
return shortuuid.New()[:12]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package service_method_same_name
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package service_method_same_name
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. service_method_same_name.proto
|
||||
@@ -0,0 +1,136 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: service_method_same_name.proto
|
||||
|
||||
package service_method_same_name
|
||||
|
||||
import (
|
||||
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 Msg struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Msg) Reset() {
|
||||
*x = Msg{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_service_method_same_name_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Msg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_service_method_same_name_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 Msg.ProtoReflect.Descriptor instead.
|
||||
func (*Msg) Descriptor() ([]byte, []int) {
|
||||
return file_service_method_same_name_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_service_method_same_name_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_service_method_same_name_proto_rawDesc = []byte{
|
||||
0x0a, 0x1e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
|
||||
0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x05, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x32, 0x1c, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12,
|
||||
0x14, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x04, 0x2e, 0x4d, 0x73, 0x67, 0x1a, 0x04, 0x2e,
|
||||
0x4d, 0x73, 0x67, 0x22, 0x00, 0x42, 0x1b, 0x5a, 0x19, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_service_method_same_name_proto_rawDescOnce sync.Once
|
||||
file_service_method_same_name_proto_rawDescData = file_service_method_same_name_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_service_method_same_name_proto_rawDescGZIP() []byte {
|
||||
file_service_method_same_name_proto_rawDescOnce.Do(func() {
|
||||
file_service_method_same_name_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_method_same_name_proto_rawDescData)
|
||||
})
|
||||
return file_service_method_same_name_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_service_method_same_name_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_service_method_same_name_proto_goTypes = []interface{}{
|
||||
(*Msg)(nil), // 0: Msg
|
||||
}
|
||||
var file_service_method_same_name_proto_depIdxs = []int32{
|
||||
0, // 0: Echo.Echo:input_type -> Msg
|
||||
0, // 1: Echo.Echo:output_type -> Msg
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_service_method_same_name_proto_init() }
|
||||
func file_service_method_same_name_proto_init() {
|
||||
if File_service_method_same_name_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_service_method_same_name_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg); 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_service_method_same_name_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_service_method_same_name_proto_goTypes,
|
||||
DependencyIndexes: file_service_method_same_name_proto_depIdxs,
|
||||
MessageInfos: file_service_method_same_name_proto_msgTypes,
|
||||
}.Build()
|
||||
File_service_method_same_name_proto = out.File
|
||||
file_service_method_same_name_proto_rawDesc = nil
|
||||
file_service_method_same_name_proto_goTypes = nil
|
||||
file_service_method_same_name_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Test to make sure that a method with the same name as its service doesn't break.
|
||||
option go_package = "/service_method_same_name";
|
||||
|
||||
message Msg {}
|
||||
|
||||
service Echo {
|
||||
rpc Echo(Msg) returns (Msg) {}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: service_method_same_name.proto
|
||||
|
||||
package service_method_same_name
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// =====================
|
||||
// Echo Client Interface
|
||||
// =====================
|
||||
|
||||
type EchoClient interface {
|
||||
Echo(context.Context, *Msg, ...psrpc.RequestOpt) (*Msg, error)
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Echo ServerImpl Interface
|
||||
// =========================
|
||||
|
||||
type EchoServerImpl interface {
|
||||
Echo(context.Context, *Msg) (*Msg, error)
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Echo Server Interface
|
||||
// =====================
|
||||
|
||||
type EchoServer interface {
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Echo Client
|
||||
// ===========
|
||||
|
||||
type echoClient struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewEchoClient creates a psrpc client that implements the EchoClient interface.
|
||||
func NewEchoClient(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (EchoClient, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("Echo", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &echoClient{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *echoClient) Echo(ctx context.Context, req *Msg, opts ...psrpc.RequestOpt) (*Msg, error) {
|
||||
return psrpc.RequestTopicSingle[*Msg](ctx, c.client, "Echo", "", req, opts...)
|
||||
}
|
||||
|
||||
// ===========
|
||||
// Echo Server
|
||||
// ===========
|
||||
|
||||
type echoServer struct {
|
||||
svc EchoServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewEchoServer builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewEchoServer(serverID string, svc EchoServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (EchoServer, error) {
|
||||
rpcServer := psrpc.NewRPCServer("Echo", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("Echo", svc.Echo))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &echoServer{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 97 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2b, 0x4e, 0x2d, 0x2a,
|
||||
0xcb, 0x4c, 0x4e, 0x8d, 0xcf, 0x4d, 0x2d, 0xc9, 0xc8, 0x4f, 0x89, 0x2f, 0x4e, 0xcc, 0x4d, 0x8d,
|
||||
0xcf, 0x4b, 0xcc, 0x4d, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x62, 0xe5, 0x62, 0xf6, 0x2d,
|
||||
0x4e, 0x37, 0x92, 0xe1, 0x62, 0x71, 0x4d, 0xce, 0xc8, 0x17, 0x12, 0x81, 0xd2, 0x2c, 0x7a, 0xbe,
|
||||
0xc5, 0xe9, 0x52, 0x60, 0x52, 0x89, 0xc1, 0x49, 0x3a, 0x4a, 0x52, 0x1f, 0x97, 0x39, 0x49, 0x6c,
|
||||
0x60, 0x83, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x97, 0x74, 0x2e, 0x74, 0x6a, 0x00, 0x00,
|
||||
0x00,
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package snake_case_names
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCompilation(t *testing.T) {
|
||||
// Test passes if this package compiles
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2019 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package snake_case_names
|
||||
|
||||
//go:generate protoc --go_out=paths=source_relative:. --psrpc_out=paths=source_relative:. snake_case_names.proto
|
||||
@@ -0,0 +1,292 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: snake_case_names.proto
|
||||
|
||||
// Test that protoc-gen-psrpc follows the same behavior as protoc-gen-go
|
||||
// for converting RPCs and message names from snake case to camel case.
|
||||
|
||||
package snake_case_names
|
||||
|
||||
import (
|
||||
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 MakeHatArgsV1 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1) Reset() {
|
||||
*x = MakeHatArgsV1{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_snake_case_names_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MakeHatArgsV1) ProtoMessage() {}
|
||||
|
||||
func (x *MakeHatArgsV1) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snake_case_names_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 MakeHatArgsV1.ProtoReflect.Descriptor instead.
|
||||
func (*MakeHatArgsV1) Descriptor() ([]byte, []int) {
|
||||
return file_snake_case_names_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type MakeHatArgsV1_HatV1 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Size int32 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Color string `protobuf:"bytes,2,opt,name=color,proto3" json:"color,omitempty"`
|
||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) Reset() {
|
||||
*x = MakeHatArgsV1_HatV1{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_snake_case_names_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MakeHatArgsV1_HatV1) ProtoMessage() {}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snake_case_names_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 MakeHatArgsV1_HatV1.ProtoReflect.Descriptor instead.
|
||||
func (*MakeHatArgsV1_HatV1) Descriptor() ([]byte, []int) {
|
||||
return file_snake_case_names_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) GetSize() int32 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) GetColor() string {
|
||||
if x != nil {
|
||||
return x.Color
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_HatV1) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MakeHatArgsV1_SizeV1 struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Inches int32 `protobuf:"varint,1,opt,name=inches,proto3" json:"inches,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_SizeV1) Reset() {
|
||||
*x = MakeHatArgsV1_SizeV1{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_snake_case_names_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_SizeV1) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MakeHatArgsV1_SizeV1) ProtoMessage() {}
|
||||
|
||||
func (x *MakeHatArgsV1_SizeV1) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_snake_case_names_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 MakeHatArgsV1_SizeV1.ProtoReflect.Descriptor instead.
|
||||
func (*MakeHatArgsV1_SizeV1) Descriptor() ([]byte, []int) {
|
||||
return file_snake_case_names_proto_rawDescGZIP(), []int{0, 1}
|
||||
}
|
||||
|
||||
func (x *MakeHatArgsV1_SizeV1) GetInches() int32 {
|
||||
if x != nil {
|
||||
return x.Inches
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_snake_case_names_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_snake_case_names_proto_rawDesc = []byte{
|
||||
0x0a, 0x16, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x24, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x73, 0x6e,
|
||||
0x61, 0x6b, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x7b,
|
||||
0x0a, 0x0e, 0x4d, 0x61, 0x6b, 0x65, 0x48, 0x61, 0x74, 0x41, 0x72, 0x67, 0x73, 0x5f, 0x76, 0x31,
|
||||
0x1a, 0x46, 0x0a, 0x06, 0x48, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69,
|
||||
0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63,
|
||||
0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x21, 0x0a, 0x07, 0x53, 0x69, 0x7a, 0x65,
|
||||
0x5f, 0x76, 0x31, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x06, 0x69, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x32, 0x9a, 0x01, 0x0a, 0x0e,
|
||||
0x48, 0x61, 0x62, 0x65, 0x72, 0x64, 0x61, 0x73, 0x68, 0x65, 0x72, 0x5f, 0x76, 0x31, 0x12, 0x87,
|
||||
0x01, 0x0a, 0x0a, 0x4d, 0x61, 0x6b, 0x65, 0x48, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x12, 0x3c, 0x2e,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x48, 0x61, 0x74, 0x41, 0x72, 0x67, 0x73,
|
||||
0x5f, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x7a, 0x65, 0x5f, 0x76, 0x31, 0x1a, 0x3b, 0x2e, 0x70, 0x73,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x74, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x2e, 0x4d, 0x61, 0x6b, 0x65, 0x48, 0x61, 0x74, 0x41, 0x72, 0x67, 0x73, 0x5f, 0x76,
|
||||
0x31, 0x2e, 0x48, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x42, 0x14, 0x5a, 0x12, 0x2f, 0x3b, 0x73, 0x6e,
|
||||
0x61, 0x6b, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_snake_case_names_proto_rawDescOnce sync.Once
|
||||
file_snake_case_names_proto_rawDescData = file_snake_case_names_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_snake_case_names_proto_rawDescGZIP() []byte {
|
||||
file_snake_case_names_proto_rawDescOnce.Do(func() {
|
||||
file_snake_case_names_proto_rawDescData = protoimpl.X.CompressGZIP(file_snake_case_names_proto_rawDescData)
|
||||
})
|
||||
return file_snake_case_names_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_snake_case_names_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_snake_case_names_proto_goTypes = []interface{}{
|
||||
(*MakeHatArgsV1)(nil), // 0: psrpc.internal.test.snake_case_names.MakeHatArgs_v1
|
||||
(*MakeHatArgsV1_HatV1)(nil), // 1: psrpc.internal.test.snake_case_names.MakeHatArgs_v1.Hat_v1
|
||||
(*MakeHatArgsV1_SizeV1)(nil), // 2: psrpc.internal.test.snake_case_names.MakeHatArgs_v1.Size_v1
|
||||
}
|
||||
var file_snake_case_names_proto_depIdxs = []int32{
|
||||
2, // 0: psrpc.internal.test.snake_case_names.Haberdasher_v1.MakeHat_v1:input_type -> psrpc.internal.test.snake_case_names.MakeHatArgs_v1.Size_v1
|
||||
1, // 1: psrpc.internal.test.snake_case_names.Haberdasher_v1.MakeHat_v1:output_type -> psrpc.internal.test.snake_case_names.MakeHatArgs_v1.Hat_v1
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_snake_case_names_proto_init() }
|
||||
func file_snake_case_names_proto_init() {
|
||||
if File_snake_case_names_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_snake_case_names_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MakeHatArgsV1); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_snake_case_names_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MakeHatArgsV1_HatV1); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_snake_case_names_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MakeHatArgsV1_SizeV1); 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_snake_case_names_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_snake_case_names_proto_goTypes,
|
||||
DependencyIndexes: file_snake_case_names_proto_depIdxs,
|
||||
MessageInfos: file_snake_case_names_proto_msgTypes,
|
||||
}.Build()
|
||||
File_snake_case_names_proto = out.File
|
||||
file_snake_case_names_proto_rawDesc = nil
|
||||
file_snake_case_names_proto_goTypes = nil
|
||||
file_snake_case_names_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Test that protoc-gen-psrpc follows the same behavior as protoc-gen-go
|
||||
// for converting RPCs and message names from snake case to camel case.
|
||||
package psrpc.internal.test.snake_case_names;
|
||||
option go_package = "/;snake_case_names";
|
||||
|
||||
message MakeHatArgs_v1 {
|
||||
message Hat_v1 {
|
||||
int32 size = 1;
|
||||
string color = 2;
|
||||
string name = 3;
|
||||
}
|
||||
|
||||
message Size_v1 {
|
||||
int32 inches = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// A Haberdasher makes hats for clients.
|
||||
service Haberdasher_v1 {
|
||||
rpc MakeHat_v1 (MakeHatArgs_v1.Size_v1) returns (MakeHatArgs_v1.Hat_v1);
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Code generated by protoc-gen-psrpc v0.0.1, DO NOT EDIT.
|
||||
// source: snake_case_names.proto
|
||||
|
||||
// Test that protoc-gen-psrpc follows the same behavior as protoc-gen-go
|
||||
// for converting RPCs and message names from snake case to camel case.
|
||||
|
||||
package snake_case_names
|
||||
|
||||
import context "context"
|
||||
|
||||
import psrpc "github.com/livekit/psrpc"
|
||||
|
||||
// ==============================
|
||||
// HaberdasherV1 Client Interface
|
||||
// ==============================
|
||||
|
||||
// A Haberdasher makes hats for clients.
|
||||
type HaberdasherV1Client interface {
|
||||
MakeHatV1(context.Context, *MakeHatArgsV1_SizeV1, ...psrpc.RequestOpt) (*MakeHatArgsV1_HatV1, error)
|
||||
}
|
||||
|
||||
// ==================================
|
||||
// HaberdasherV1 ServerImpl Interface
|
||||
// ==================================
|
||||
|
||||
// A Haberdasher makes hats for clients.
|
||||
type HaberdasherV1ServerImpl interface {
|
||||
MakeHatV1(context.Context, *MakeHatArgsV1_SizeV1) (*MakeHatArgsV1_HatV1, error)
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// HaberdasherV1 Server Interface
|
||||
// ==============================
|
||||
|
||||
// A Haberdasher makes hats for clients.
|
||||
type HaberdasherV1Server interface {
|
||||
}
|
||||
|
||||
// ====================
|
||||
// HaberdasherV1 Client
|
||||
// ====================
|
||||
|
||||
type haberdasherV1Client struct {
|
||||
client psrpc.RPCClient
|
||||
}
|
||||
|
||||
// NewHaberdasherV1Client creates a psrpc client that implements the HaberdasherV1Client interface.
|
||||
func NewHaberdasherV1Client(clientID string, bus psrpc.MessageBus, opts ...psrpc.ClientOpt) (HaberdasherV1Client, error) {
|
||||
rpcClient, err := psrpc.NewRPCClient("HaberdasherV1", clientID, bus, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &haberdasherV1Client{
|
||||
client: rpcClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *haberdasherV1Client) MakeHatV1(ctx context.Context, req *MakeHatArgsV1_SizeV1, opts ...psrpc.RequestOpt) (*MakeHatArgsV1_HatV1, error) {
|
||||
return psrpc.RequestTopicSingle[*MakeHatArgsV1_HatV1](ctx, c.client, "MakeHatV1", "", req, opts...)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// HaberdasherV1 Server
|
||||
// ====================
|
||||
|
||||
type haberdasherV1Server struct {
|
||||
svc HaberdasherV1ServerImpl
|
||||
rpc psrpc.RPCServer
|
||||
}
|
||||
|
||||
// NewHaberdasherV1Server builds a RPCServer that can be used to handle
|
||||
// requests that are routed to the right method in the provided svc implementation.
|
||||
func NewHaberdasherV1Server(serverID string, svc HaberdasherV1ServerImpl, bus psrpc.MessageBus, opts ...psrpc.ServerOpt) (HaberdasherV1Server, error) {
|
||||
rpcServer := psrpc.NewRPCServer("HaberdasherV1", serverID, bus, opts...)
|
||||
|
||||
var err error
|
||||
err = rpcServer.RegisterHandler(psrpc.NewHandler("MakeHatV1", svc.MakeHatV1))
|
||||
if err != nil {
|
||||
rpcServer.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &haberdasherV1Server{
|
||||
svc: svc,
|
||||
rpc: rpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var psrpcFileDescriptor0 = []byte{
|
||||
// 225 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2b, 0xce, 0x4b, 0xcc,
|
||||
0x4e, 0x8d, 0x4f, 0x4e, 0x2c, 0x4e, 0x8d, 0xcf, 0x4b, 0xcc, 0x4d, 0x2d, 0xd6, 0x2b, 0x28, 0xca,
|
||||
0x2f, 0xc9, 0x17, 0x52, 0x29, 0x28, 0x2e, 0x2a, 0x48, 0xd6, 0xcb, 0xcc, 0x2b, 0x49, 0x2d, 0xca,
|
||||
0x4b, 0xcc, 0xd1, 0x2b, 0x49, 0x2d, 0x2e, 0xd1, 0x43, 0x57, 0xab, 0x54, 0xcd, 0xc5, 0xe7, 0x9b,
|
||||
0x98, 0x9d, 0xea, 0x91, 0x58, 0xe2, 0x58, 0x94, 0x5e, 0x1c, 0x5f, 0x66, 0x28, 0xe5, 0xc6, 0xc5,
|
||||
0xe6, 0x91, 0x58, 0x12, 0x5f, 0x66, 0x28, 0x24, 0xc4, 0xc5, 0x52, 0x9c, 0x59, 0x95, 0x2a, 0xc1,
|
||||
0xa8, 0xc0, 0xa8, 0xc1, 0x1a, 0x04, 0x66, 0x0b, 0x89, 0x70, 0xb1, 0x26, 0xe7, 0xe7, 0xe4, 0x17,
|
||||
0x49, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x06, 0x41, 0x38, 0x20, 0x95, 0x20, 0xe3, 0x24, 0x98, 0xc1,
|
||||
0x82, 0x60, 0xb6, 0x94, 0x22, 0x17, 0x7b, 0x70, 0x66, 0x55, 0x2a, 0xc8, 0x20, 0x31, 0x2e, 0xb6,
|
||||
0xcc, 0xbc, 0xe4, 0x8c, 0xd4, 0x62, 0xa8, 0x51, 0x50, 0x9e, 0xd1, 0x2c, 0x46, 0x2e, 0x3e, 0x8f,
|
||||
0xc4, 0xa4, 0xd4, 0xa2, 0x94, 0xc4, 0xe2, 0x8c, 0xd4, 0x22, 0x90, 0xd2, 0x76, 0x46, 0x2e, 0x2e,
|
||||
0xa8, 0x83, 0x40, 0x5c, 0x1b, 0x3d, 0x62, 0x7c, 0xa1, 0x87, 0xea, 0x05, 0x3d, 0xa8, 0xbd, 0x52,
|
||||
0xd6, 0x64, 0xe9, 0x86, 0x58, 0xed, 0x24, 0x12, 0x25, 0xa4, 0x6f, 0x8d, 0xae, 0x36, 0x89, 0x0d,
|
||||
0x1c, 0xb8, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x4f, 0x4c, 0xcd, 0x76, 0x01, 0x00,
|
||||
0x00,
|
||||
}
|
||||
+55
-11
@@ -14,13 +14,12 @@ import (
|
||||
|
||||
var Default = Test
|
||||
|
||||
// regenerate protobuf
|
||||
func Install() error {
|
||||
return mageutil.Run(context.Background(), "go install ./protoc-gen-psrpc")
|
||||
}
|
||||
|
||||
func Proto() error {
|
||||
fmt.Println("generating protobuf")
|
||||
target := "internal"
|
||||
if err := os.MkdirAll(target, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protoc, err := mageutil.GetToolPath("protoc")
|
||||
if err != nil {
|
||||
@@ -32,18 +31,63 @@ func Proto() error {
|
||||
}
|
||||
|
||||
cmd := exec.Command(protoc,
|
||||
"--go_out", target,
|
||||
"--go-grpc_out", target,
|
||||
"--go_out", "internal",
|
||||
"--go_opt=paths=source_relative",
|
||||
"--go-grpc_opt=paths=source_relative",
|
||||
"--plugin=go="+protocGoPath,
|
||||
"-I=.",
|
||||
"-I=./internal",
|
||||
"internal.proto",
|
||||
)
|
||||
mageutil.ConnectStd(cmd)
|
||||
return cmd.Run()
|
||||
if err = cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command(protoc,
|
||||
"--go_out", "protoc-gen-psrpc/options",
|
||||
"--go_opt=paths=source_relative",
|
||||
"--plugin=go="+protocGoPath,
|
||||
"-I=./protoc-gen-psrpc/options",
|
||||
"options.proto",
|
||||
)
|
||||
mageutil.ConnectStd(cmd)
|
||||
if err = cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Generate() error {
|
||||
ctx := context.Background()
|
||||
|
||||
err := mageutil.Run(ctx, "go install ./protoc-gen-psrpc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
base := "./internal/test"
|
||||
dirs, err := os.ReadDir(base)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, dir := range dirs {
|
||||
if dir.IsDir() {
|
||||
err = mageutil.RunDir(ctx, fmt.Sprintf("%s/%s", base, dir.Name()), "go generate .")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test() error {
|
||||
return mageutil.Run(context.Background(), "go test -v ./...")
|
||||
return mageutil.Run(context.Background(), "go test -v .")
|
||||
}
|
||||
|
||||
func TestAll() error {
|
||||
if err := Generate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return mageutil.Run(context.Background(), "go test ./...")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type commandLineParams struct {
|
||||
importMap map[string]string // Mapping from .proto file name to import path.
|
||||
paths string // paths flag, used to control file output directory.
|
||||
module string // module flag, Go import path prefix that is removed from the output filename.
|
||||
importPrefix string // prefix added to imported package file names.
|
||||
}
|
||||
|
||||
// parseCommandLineParams breaks the comma-separated list of key=value pairs
|
||||
// in the parameter (a member of the request protobuf) into a key/value map.
|
||||
// It then sets command line parameter mappings defined by those entries.
|
||||
func parseCommandLineParams(parameter string) (*commandLineParams, error) {
|
||||
ps := make(map[string]string)
|
||||
for _, p := range strings.Split(parameter, ",") {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
i := strings.Index(p, "=")
|
||||
if i < 0 {
|
||||
return nil, fmt.Errorf("invalid parameter %q: expected format of parameter to be k=v", p)
|
||||
}
|
||||
k := p[0:i]
|
||||
v := p[i+1:]
|
||||
if v == "" {
|
||||
return nil, fmt.Errorf("invalid parameter %q: expected format of parameter to be k=v", k)
|
||||
}
|
||||
ps[k] = v
|
||||
}
|
||||
|
||||
clp := &commandLineParams{
|
||||
importMap: make(map[string]string),
|
||||
}
|
||||
for k, v := range ps {
|
||||
switch {
|
||||
// Support import map 'M' prefix: https://developers.google.com/protocol-buffers/docs/reference/go-generated
|
||||
case len(k) > 0 && k[0] == 'M':
|
||||
clp.importMap[k[1:]] = v // 1 is the length of 'M'.
|
||||
case len(k) > 0 && strings.HasPrefix(k, "go_import_mapping@"): // twirp specific version of M parameters
|
||||
clp.importMap[k[18:]] = v // 18 is the length of 'go_import_mapping@'.
|
||||
|
||||
case k == "paths":
|
||||
switch v {
|
||||
case "import":
|
||||
// this is the default behavior; the output file is placed in a directory named after the option go_package
|
||||
case "source_relative":
|
||||
// the directory prefix on the option go_package is removed from the output filename (only the last part is used)
|
||||
clp.paths = "source_relative"
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid command line flag %s=%s", k, v)
|
||||
}
|
||||
|
||||
// If the module={PREFIX} flag is specified, the prefix is removed from the option go_package on the output filename
|
||||
case k == "module":
|
||||
clp.module = v
|
||||
|
||||
// Deprecated, but may still be useful when working with old versions of protoc-gen-go
|
||||
case k == "import_prefix":
|
||||
clp.importPrefix = v
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid command line flag %s=%s", k, v)
|
||||
}
|
||||
}
|
||||
return clp, nil
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseCommandLineParams(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
parameter string
|
||||
params *commandLineParams
|
||||
err error
|
||||
}{
|
||||
{
|
||||
"no parameters",
|
||||
"",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"unknown parameter",
|
||||
"kkk=vvv",
|
||||
nil,
|
||||
errors.New(`invalid command line flag kkk=vvv`),
|
||||
},
|
||||
{
|
||||
"empty parameter value - no equals sign",
|
||||
"import_prefix",
|
||||
nil,
|
||||
errors.New(`invalid parameter "import_prefix": expected format of parameter to be k=v`),
|
||||
},
|
||||
{
|
||||
"empty parameter value - no value",
|
||||
"import_prefix=",
|
||||
nil,
|
||||
errors.New(`invalid parameter "import_prefix": expected format of parameter to be k=v`),
|
||||
},
|
||||
{
|
||||
"import_prefix parameter",
|
||||
"import_prefix=github.com/example/repo",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{},
|
||||
importPrefix: "github.com/example/repo",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"single import parameter starting with 'M'",
|
||||
"Mrpcutil/empty.proto=github.com/example/rpcutil",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{
|
||||
"rpcutil/empty.proto": "github.com/example/rpcutil",
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"multiple import parameters starting with 'M'",
|
||||
"Mrpcutil/empty.proto=github.com/example/rpcutil,Mrpc/haberdasher/service.proto=github.com/example/rpc/haberdasher",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{
|
||||
"rpcutil/empty.proto": "github.com/example/rpcutil",
|
||||
"rpc/haberdasher/service.proto": "github.com/example/rpc/haberdasher",
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"single import parameter starting with 'go_import_mapping@'",
|
||||
"go_import_mapping@rpcutil/empty.proto=github.com/example/rpcutil",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{
|
||||
"rpcutil/empty.proto": "github.com/example/rpcutil",
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"multiple import parameters starting with 'go_import_mapping@'",
|
||||
"go_import_mapping@rpcutil/empty.proto=github.com/example/rpcutil,go_import_mapping@rpc/haberdasher/service.proto=github.com/example/rpc/haberdasher",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{
|
||||
"rpcutil/empty.proto": "github.com/example/rpcutil",
|
||||
"rpc/haberdasher/service.proto": "github.com/example/rpc/haberdasher",
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"paths import",
|
||||
"paths=import",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"paths source_relative",
|
||||
"paths=source_relative",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{},
|
||||
paths: "source_relative",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"paths invalidstuff",
|
||||
"paths=invalidstuff",
|
||||
nil,
|
||||
errors.New(`invalid command line flag paths=invalidstuff`),
|
||||
},
|
||||
{
|
||||
"module parameter",
|
||||
"module=foo/bar/fizz",
|
||||
&commandLineParams{
|
||||
importMap: map[string]string{},
|
||||
module: "foo/bar/fizz",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
params, err := parseCommandLineParams(tt.parameter)
|
||||
switch {
|
||||
case err != nil:
|
||||
if tt.err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err.Error() != tt.err.Error() {
|
||||
t.Errorf("got error = %v, want %v", err, tt.err)
|
||||
}
|
||||
case err == nil:
|
||||
if tt.err != nil {
|
||||
t.Errorf("got error = %v, want %v", err, tt.err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(params, tt.params) {
|
||||
t.Errorf("got params = %+v, want %+v", params, tt.params)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,753 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
plugin "google.golang.org/protobuf/types/pluginpb"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/livekit/psrpc/internal/gen"
|
||||
"github.com/livekit/psrpc/internal/gen/stringutils"
|
||||
"github.com/livekit/psrpc/internal/gen/typemap"
|
||||
"github.com/livekit/psrpc/protoc-gen-psrpc/options"
|
||||
)
|
||||
|
||||
type psrpc struct {
|
||||
filesHandled int
|
||||
|
||||
reg *typemap.Registry
|
||||
|
||||
// Map to record whether we've built each package
|
||||
pkgs map[string]string
|
||||
pkgNamesInUse map[string]bool
|
||||
|
||||
importPrefix string // String to prefix to imported package file names.
|
||||
importMap map[string]string // Mapping from .proto file name to import path.
|
||||
|
||||
// Package output:
|
||||
sourceRelativePaths bool // instruction on where to write output files
|
||||
modulePrefix string
|
||||
|
||||
// Package naming:
|
||||
genPkgName string // Name of the package that we're generating
|
||||
fileToGoPackageName map[*descriptor.FileDescriptorProto]string
|
||||
|
||||
// List of files that were inputs to the generator. We need to hold this in
|
||||
// the struct, so we can write a header for the file that lists its inputs.
|
||||
genFiles []*descriptor.FileDescriptorProto
|
||||
|
||||
// Output buffer that holds the bytes we want to write out for a single file.
|
||||
// Gets reset after working on a file.
|
||||
output *bytes.Buffer
|
||||
}
|
||||
|
||||
func newGenerator() *psrpc {
|
||||
t := &psrpc{
|
||||
pkgs: make(map[string]string),
|
||||
pkgNamesInUse: make(map[string]bool),
|
||||
importMap: make(map[string]string),
|
||||
fileToGoPackageName: make(map[*descriptor.FileDescriptorProto]string),
|
||||
output: bytes.NewBuffer(nil),
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *psrpc) Generate(in *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse {
|
||||
params, err := parseCommandLineParams(in.GetParameter())
|
||||
if err != nil {
|
||||
gen.Fail("could not parse parameters passed to --psrpc_out", err.Error())
|
||||
}
|
||||
t.importPrefix = params.importPrefix
|
||||
t.importMap = params.importMap
|
||||
t.sourceRelativePaths = params.paths == "source_relative"
|
||||
t.modulePrefix = params.module
|
||||
|
||||
t.genFiles = gen.FilesToGenerate(in)
|
||||
|
||||
// Collect information on types.
|
||||
t.reg = typemap.New(in.ProtoFile)
|
||||
|
||||
// Register names of packages that we import.
|
||||
t.registerPackageName("context")
|
||||
t.registerPackageName("psrpc")
|
||||
|
||||
// Time to figure out package names of objects defined in protobuf. First,
|
||||
// we'll figure out the name for the package we're generating.
|
||||
genPkgName, err := deduceGenPkgName(t.genFiles)
|
||||
if err != nil {
|
||||
gen.Fail(err.Error())
|
||||
}
|
||||
t.genPkgName = genPkgName
|
||||
|
||||
// We also need to figure out the full import path of the package we're
|
||||
// generating. It's possible to import proto definitions from different .proto
|
||||
// files which will be generated into the same Go package, which we need to
|
||||
// detect (and can only detect if files use fully-specified go_package
|
||||
// options).
|
||||
genPkgImportPath, _, _ := goPackageOption(t.genFiles[0])
|
||||
|
||||
// Next, we need to pick names for all the files that are dependencies.
|
||||
for _, f := range in.ProtoFile {
|
||||
// Is this is a file we are generating? If yes, it gets the shared package name.
|
||||
if fileDescSliceContains(t.genFiles, f) {
|
||||
t.fileToGoPackageName[f] = t.genPkgName
|
||||
continue
|
||||
}
|
||||
|
||||
// Is this is an imported .proto file which has the same fully-specified
|
||||
// go_package as the targeted file for generation? If yes, it gets the
|
||||
// shared package name too.
|
||||
if genPkgImportPath != "" {
|
||||
importPath, _, _ := goPackageOption(f)
|
||||
if importPath == genPkgImportPath {
|
||||
t.fileToGoPackageName[f] = t.genPkgName
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// This is a dependency from a different go_package. Use its package name.
|
||||
name := f.GetPackage()
|
||||
if name == "" {
|
||||
name = stringutils.BaseName(f.GetName())
|
||||
}
|
||||
name = stringutils.CleanIdentifier(name)
|
||||
alias := t.registerPackageName(name)
|
||||
t.fileToGoPackageName[f] = alias
|
||||
}
|
||||
|
||||
// Showtime! Generate the response.
|
||||
resp := new(plugin.CodeGeneratorResponse)
|
||||
resp.SupportedFeatures = proto.Uint64(uint64(plugin.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL))
|
||||
for _, f := range t.genFiles {
|
||||
respFile := t.generate(f)
|
||||
if respFile != nil {
|
||||
resp.File = append(resp.File, respFile)
|
||||
}
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func (t *psrpc) registerPackageName(name string) (alias string) {
|
||||
alias = name
|
||||
i := 1
|
||||
for t.pkgNamesInUse[alias] {
|
||||
alias = name + strconv.Itoa(i)
|
||||
i++
|
||||
}
|
||||
t.pkgNamesInUse[alias] = true
|
||||
t.pkgs[name] = alias
|
||||
return alias
|
||||
}
|
||||
|
||||
// deduceGenPkgName figures out the go package name to use for generated code.
|
||||
// Will try to use the explicit go_package setting in a file (if set, must be
|
||||
// consistent in all files). If no files have go_package set, then use the
|
||||
// protobuf package name (must be consistent in all files)
|
||||
func deduceGenPkgName(genFiles []*descriptor.FileDescriptorProto) (string, error) {
|
||||
var genPkgName string
|
||||
for _, f := range genFiles {
|
||||
name, explicit := goPackageName(f)
|
||||
if explicit {
|
||||
name = stringutils.CleanIdentifier(name)
|
||||
if genPkgName != "" && genPkgName != name {
|
||||
// Make sure they're all set consistently.
|
||||
return "", errors.Errorf("files have conflicting go_package settings, must be the same: %q and %q", genPkgName, name)
|
||||
}
|
||||
genPkgName = name
|
||||
}
|
||||
}
|
||||
if genPkgName != "" {
|
||||
return genPkgName, nil
|
||||
}
|
||||
|
||||
// If there is no explicit setting, then check the implicit package name
|
||||
// (derived from the protobuf package name) of the files and make sure it's
|
||||
// consistent.
|
||||
for _, f := range genFiles {
|
||||
name, _ := goPackageName(f)
|
||||
name = stringutils.CleanIdentifier(name)
|
||||
if genPkgName != "" && genPkgName != name {
|
||||
return "", errors.Errorf("files have conflicting package names, must be the same or overridden with go_package: %q and %q", genPkgName, name)
|
||||
}
|
||||
genPkgName = name
|
||||
}
|
||||
|
||||
// All the files have the same name, so we're good.
|
||||
return genPkgName, nil
|
||||
}
|
||||
|
||||
func (t *psrpc) generate(file *descriptor.FileDescriptorProto) *plugin.CodeGeneratorResponse_File {
|
||||
resp := new(plugin.CodeGeneratorResponse_File)
|
||||
if len(file.Service) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.generateFileHeader(file)
|
||||
t.generateImports(file)
|
||||
|
||||
// For each service, generate client stubs and server
|
||||
for _, service := range file.Service {
|
||||
t.generateService(file, service)
|
||||
}
|
||||
|
||||
t.generateFileDescriptor(file)
|
||||
|
||||
resp.Name = proto.String(t.goFileName(file))
|
||||
resp.Content = proto.String(t.formattedOutput())
|
||||
t.output.Reset()
|
||||
|
||||
t.filesHandled++
|
||||
return resp
|
||||
}
|
||||
|
||||
func (t *psrpc) generateFileHeader(file *descriptor.FileDescriptorProto) {
|
||||
t.P("// Code generated by protoc-gen-psrpc ", gen.Version, ", DO NOT EDIT.")
|
||||
t.P("// source: ", file.GetName())
|
||||
t.P()
|
||||
|
||||
comment, err := t.reg.FileComments(file)
|
||||
if err == nil && comment.Leading != "" {
|
||||
for _, line := range strings.Split(comment.Leading, "\n") {
|
||||
if line != "" {
|
||||
t.P("// " + strings.TrimPrefix(line, " "))
|
||||
}
|
||||
}
|
||||
t.P()
|
||||
}
|
||||
|
||||
t.P(`package `, t.genPkgName)
|
||||
t.P()
|
||||
}
|
||||
|
||||
func (t *psrpc) generateImports(file *descriptor.FileDescriptorProto) {
|
||||
if len(file.Service) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// stdlib imports
|
||||
for _, service := range file.Service {
|
||||
if len(service.Method) > 0 {
|
||||
t.P(`import `, t.pkgs["context"], ` "context"`)
|
||||
t.P()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// dependency imports
|
||||
t.P(`import `, t.pkgs["psrpc"], ` "github.com/livekit/psrpc"`)
|
||||
|
||||
// It's legal to import a message and use it as an input or output for a
|
||||
// method. Make sure to import the package of any such message. First, dedupe
|
||||
// them.
|
||||
deps := make(map[string]string) // Map of package name to quoted import path.
|
||||
ourImportPath := path.Dir(t.goFileName(file))
|
||||
for _, s := range file.Service {
|
||||
for _, m := range s.Method {
|
||||
defs := []*typemap.MessageDefinition{
|
||||
t.reg.MethodInputDefinition(m),
|
||||
t.reg.MethodOutputDefinition(m),
|
||||
}
|
||||
for _, def := range defs {
|
||||
importPath, _ := parseGoPackageOption(def.File.GetOptions().GetGoPackage())
|
||||
if importPath == "" { // no option go_package
|
||||
importPath := path.Dir(t.goFileName(def.File)) // use the dirname of the Go filename as import path
|
||||
if importPath == ourImportPath {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if substitution, ok := t.importMap[def.File.GetName()]; ok {
|
||||
importPath = substitution
|
||||
}
|
||||
importPath = t.importPrefix + importPath
|
||||
|
||||
pkg := t.goPackageName(def.File)
|
||||
if pkg != t.genPkgName {
|
||||
deps[pkg] = strconv.Quote(importPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pkgs := make([]string, 0, len(deps))
|
||||
for pkg := range deps {
|
||||
pkgs = append(pkgs, pkg)
|
||||
}
|
||||
sort.Strings(pkgs)
|
||||
for _, pkg := range pkgs {
|
||||
t.P(`import `, pkg, ` `, deps[pkg])
|
||||
}
|
||||
if len(deps) > 0 {
|
||||
t.P()
|
||||
}
|
||||
}
|
||||
|
||||
// W forwards to g.gen.P, which prints output.
|
||||
func (t *psrpc) W(args ...string) {
|
||||
for _, v := range args {
|
||||
t.output.WriteString(v)
|
||||
}
|
||||
}
|
||||
|
||||
// P forwards to g.gen.P, which prints output.
|
||||
func (t *psrpc) P(args ...string) {
|
||||
for _, v := range args {
|
||||
t.output.WriteString(v)
|
||||
}
|
||||
t.output.WriteByte('\n')
|
||||
}
|
||||
|
||||
// Big header comments to makes it easier to visually parse a generated file.
|
||||
func (t *psrpc) sectionComment(sectionTitle string) {
|
||||
t.P()
|
||||
t.P(`// `, strings.Repeat("=", len(sectionTitle)))
|
||||
t.P(`// `, sectionTitle)
|
||||
t.P(`// `, strings.Repeat("=", len(sectionTitle)))
|
||||
t.P()
|
||||
}
|
||||
|
||||
const (
|
||||
client = "Client"
|
||||
ServerImpl = "ServerImpl"
|
||||
server = "Server"
|
||||
)
|
||||
|
||||
func (t *psrpc) generateService(file *descriptor.FileDescriptorProto, service *descriptor.ServiceDescriptorProto) {
|
||||
servName := serviceNameCamelCased(service)
|
||||
|
||||
t.sectionComment(servName + ` Client Interface`)
|
||||
t.generateInterface(file, service, client)
|
||||
|
||||
t.sectionComment(servName + ` ServerImpl Interface`)
|
||||
t.generateInterface(file, service, ServerImpl)
|
||||
|
||||
t.sectionComment(servName + ` Server Interface`)
|
||||
t.generateInterface(file, service, server)
|
||||
|
||||
t.sectionComment(servName + ` Client`)
|
||||
t.generateClient(service)
|
||||
|
||||
t.sectionComment(servName + ` Server`)
|
||||
t.generateServer(service)
|
||||
}
|
||||
|
||||
func (t *psrpc) generateInterface(file *descriptor.FileDescriptorProto, service *descriptor.ServiceDescriptorProto, iface string) {
|
||||
servName := serviceNameCamelCased(service)
|
||||
|
||||
comments, err := t.reg.ServiceComments(file, service)
|
||||
if err == nil {
|
||||
t.printComments(comments)
|
||||
}
|
||||
|
||||
t.P(`type `, servName, iface, ` interface {`)
|
||||
for _, method := range service.Method {
|
||||
opts := t.getOptions(method)
|
||||
if (iface == ServerImpl && opts.Subscription) || (iface == server && !opts.Subscription && !opts.Topics) {
|
||||
continue
|
||||
}
|
||||
|
||||
comments, err = t.reg.MethodComments(file, service, method)
|
||||
if err == nil {
|
||||
t.printComments(comments)
|
||||
}
|
||||
switch iface {
|
||||
case client:
|
||||
t.generateClientSignature(method, opts)
|
||||
case ServerImpl:
|
||||
t.generateServerImplSignature(method, opts)
|
||||
case server:
|
||||
t.generateServerSignature(method, opts)
|
||||
}
|
||||
}
|
||||
t.P(`}`)
|
||||
}
|
||||
|
||||
func (t *psrpc) generateClientSignature(method *descriptor.MethodDescriptorProto, opts *options.Options) {
|
||||
methName := methodNameCamelCased(method)
|
||||
inputType := t.goTypeName(method.GetInputType())
|
||||
outputType := t.goTypeName(method.GetOutputType())
|
||||
|
||||
if opts.Subscription {
|
||||
t.W(` Subscribe`)
|
||||
} else {
|
||||
t.W(` `)
|
||||
}
|
||||
t.W(methName, `(`, t.pkgs["context"], `.Context`)
|
||||
if opts.Topics {
|
||||
t.W(`, string`)
|
||||
}
|
||||
if opts.Subscription {
|
||||
t.P(`) (`, t.pkgs["psrpc"], `.Subscription[*`, outputType, `], error)`)
|
||||
} else if opts.Multi {
|
||||
t.P(`, *`, inputType, `, ...`, t.pkgs["psrpc"], `.RequestOpt) (<-chan *`, t.pkgs["psrpc"], `.Response[*`, outputType, `], error)`)
|
||||
} else {
|
||||
t.P(`, *`, inputType, `, ...`, t.pkgs["psrpc"], `.RequestOpt) (*`, outputType, `, error)`)
|
||||
}
|
||||
t.P()
|
||||
}
|
||||
|
||||
func (t *psrpc) generateClient(service *descriptor.ServiceDescriptorProto) {
|
||||
servName := serviceNameCamelCased(service)
|
||||
structName := unexported(servName) + "Client"
|
||||
newClientFunc := "New" + servName + "Client"
|
||||
|
||||
t.P(`type `, structName, ` struct {`)
|
||||
t.P(` client `, t.pkgs["psrpc"], `.RPCClient`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
|
||||
t.P(`// `, newClientFunc, ` creates a psrpc client that implements the `, servName, `Client interface.`)
|
||||
t.P(`func `, newClientFunc, `(clientID string, bus `, t.pkgs["psrpc"], `.MessageBus, opts ...`, t.pkgs["psrpc"], `.ClientOpt) (`, servName, `Client, error) {`)
|
||||
t.P(` rpcClient, err := `, t.pkgs["psrpc"], `.NewRPCClient("`, servName, `", clientID, bus, opts...)`)
|
||||
t.P(` if err != nil {`)
|
||||
t.P(` return nil, err`)
|
||||
t.P(` }`)
|
||||
t.P()
|
||||
t.P(` return &`, structName, `{`)
|
||||
t.P(` client: rpcClient,`)
|
||||
t.P(` }, nil`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
|
||||
for _, method := range service.Method {
|
||||
methName := methodNameCamelCased(method)
|
||||
inputType := t.goTypeName(method.GetInputType())
|
||||
outputType := t.goTypeName(method.GetOutputType())
|
||||
opts := t.getOptions(method)
|
||||
|
||||
topicParam := `""`
|
||||
t.W(`func (c *`, structName)
|
||||
if opts.Subscription {
|
||||
t.W(`) Subscribe`)
|
||||
} else {
|
||||
t.W(`) `)
|
||||
}
|
||||
t.W(methName, `(ctx `, t.pkgs["context"], `.Context`)
|
||||
if opts.Topics {
|
||||
topicParam = "topic"
|
||||
t.W(`, topic string`)
|
||||
}
|
||||
if opts.Subscription {
|
||||
t.P(`) (`, t.pkgs["psrpc"], `.Subscription[*`, outputType, `], error)`, ` {`)
|
||||
} else {
|
||||
t.W(`, req *`, inputType, `, opts ...`, t.pkgs["psrpc"], `.RequestOpt`)
|
||||
if opts.Multi {
|
||||
t.P(`) (<-chan *`, t.pkgs["psrpc"], `.Response[*`, outputType, `], error)`, ` {`)
|
||||
} else {
|
||||
t.P(`) (*`, outputType, `, error)`, ` {`)
|
||||
}
|
||||
}
|
||||
|
||||
t.W(` return `, t.pkgs["psrpc"])
|
||||
if opts.Subscription {
|
||||
if opts.Multi {
|
||||
t.W(`.SubscribeTopic[*`)
|
||||
} else {
|
||||
t.W(`.SubscribeTopicQueue[*`)
|
||||
}
|
||||
t.P(outputType, `](ctx, c.client, "`, methName, `", `, topicParam, `)`)
|
||||
} else {
|
||||
if opts.Multi {
|
||||
t.W(`.RequestTopicAll[*`)
|
||||
} else {
|
||||
t.W(`.RequestTopicSingle[*`)
|
||||
}
|
||||
t.P(outputType, `](ctx, c.client, "`, methName, `", `, topicParam, `, req, opts...)`)
|
||||
}
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *psrpc) generateServerImplSignature(method *descriptor.MethodDescriptorProto, opts *options.Options) {
|
||||
methName := methodNameCamelCased(method)
|
||||
inputType := t.goTypeName(method.GetInputType())
|
||||
outputType := t.goTypeName(method.GetOutputType())
|
||||
|
||||
t.P(` `, methName, `(`, t.pkgs["context"], `.Context, *`, inputType, `) (*`, outputType, `, error)`)
|
||||
if opts.AffinityFunc {
|
||||
t.P(` `, methName, `Affinity(*`, inputType, `) float32`)
|
||||
}
|
||||
t.P()
|
||||
}
|
||||
|
||||
func (t *psrpc) generateServerSignature(method *descriptor.MethodDescriptorProto, opts *options.Options) {
|
||||
methName := methodNameCamelCased(method)
|
||||
outputType := t.goTypeName(method.GetOutputType())
|
||||
|
||||
if opts.Subscription {
|
||||
t.W(` Publish`, methName, `(`, t.pkgs["context"], `.Context`)
|
||||
if opts.Topics {
|
||||
t.W(`, string`)
|
||||
}
|
||||
t.P(`, *`, outputType, `) error`)
|
||||
t.P()
|
||||
} else {
|
||||
t.P(` Register`, methName, `Topic(string) error`)
|
||||
t.P(` Deregister`, methName, `Topic(string) error`)
|
||||
t.P()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *psrpc) generateServer(service *descriptor.ServiceDescriptorProto) {
|
||||
servName := serviceNameCamelCased(service)
|
||||
|
||||
// Server implementation.
|
||||
servStruct := serviceStruct(service)
|
||||
t.P(`type `, servStruct, ` struct {`)
|
||||
t.P(` svc `, servName, `ServerImpl`)
|
||||
t.P(` rpc `, t.pkgs["psrpc"], `.RPCServer`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
|
||||
// Constructor for server implementation
|
||||
t.P(`// New`, servName, `Server builds a RPCServer that can be used to handle`)
|
||||
t.P(`// requests that are routed to the right method in the provided svc implementation.`)
|
||||
t.P(`func New`, servName, `Server(serverID string, svc `, servName, `ServerImpl, bus `, t.pkgs["psrpc"], `.MessageBus, opts ...`, t.pkgs["psrpc"], `.ServerOpt) (`, servName, `Server, error) {`)
|
||||
t.P(` rpcServer := `, t.pkgs["psrpc"], `.NewRPCServer("`, servName, `", serverID, bus, opts...)`)
|
||||
t.P()
|
||||
|
||||
errVar := false
|
||||
for _, method := range service.Method {
|
||||
opts := t.getOptions(method)
|
||||
if opts.Subscription || opts.Topics {
|
||||
continue
|
||||
}
|
||||
|
||||
if !errVar {
|
||||
t.P(` var err error`)
|
||||
errVar = true
|
||||
}
|
||||
|
||||
methName := methodNameCamelCased(method)
|
||||
t.W(` err = rpcServer.RegisterHandler(`, t.pkgs["psrpc"])
|
||||
if t.getOptions(method).AffinityFunc {
|
||||
t.P(`.NewHandlerWithAffinity("`, methName, `", svc.`, methName, `, svc.`, methName, `Affinity))`)
|
||||
} else {
|
||||
t.P(`.NewHandler("`, methName, `", svc.`, methName, `))`)
|
||||
}
|
||||
t.P(` if err != nil {`)
|
||||
t.P(` rpcServer.Close()`)
|
||||
t.P(` return nil, err`)
|
||||
t.P(` }`)
|
||||
t.P()
|
||||
}
|
||||
|
||||
t.P(` return &`, servStruct, `{`)
|
||||
t.P(` svc: svc,`)
|
||||
t.P(` rpc: rpcServer,`)
|
||||
t.P(` }, nil`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
|
||||
for _, method := range service.Method {
|
||||
opts := t.getOptions(method)
|
||||
if !opts.Subscription && !opts.Topics {
|
||||
continue
|
||||
}
|
||||
|
||||
methName := methodNameCamelCased(method)
|
||||
outputType := t.goTypeName(method.GetOutputType())
|
||||
|
||||
if opts.Subscription {
|
||||
topicParam := `""`
|
||||
t.W(`func (s *`, servStruct, `) Publish`, methName, `(ctx `, t.pkgs["context"], `.Context`)
|
||||
if opts.Topics {
|
||||
topicParam = `topic`
|
||||
t.W(`, topic string`)
|
||||
}
|
||||
t.P(`, msg *`, outputType, `) error {`)
|
||||
t.P(` return s.rpc.PublishTopic(ctx, "`, methName, `", `, topicParam, `, msg)`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
} else {
|
||||
t.P(`func (s *`, servStruct, `) Register`, methName, `Topic(topic string) error {`)
|
||||
t.W(` return s.rpc.RegisterHandler(`, t.pkgs["psrpc"])
|
||||
if t.getOptions(method).AffinityFunc {
|
||||
t.P(`.NewTopicHandlerWithAffinity("`, methName, `", topic, s.svc.`, methName, `, s.svc.`, methName, `Affinity))`)
|
||||
} else {
|
||||
t.P(`.NewTopicHandler("`, methName, `", topic, s.svc.`, methName, `))`)
|
||||
}
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
t.P(`func (s *`, servStruct, `) Deregister`, methName, `Topic(topic string) error {`)
|
||||
t.P(` return s.rpc.DeregisterTopic("`, methName, `", topic)`)
|
||||
t.P(`}`)
|
||||
t.P()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *psrpc) getOptions(method *descriptor.MethodDescriptorProto) *options.Options {
|
||||
if method.Options == nil {
|
||||
return &options.Options{}
|
||||
}
|
||||
|
||||
if proto.HasExtension(method.Options, options.E_Options) {
|
||||
ext := proto.GetExtension(method.Options, options.E_Options)
|
||||
return ext.(*options.Options)
|
||||
}
|
||||
|
||||
return &options.Options{}
|
||||
}
|
||||
|
||||
// serviceMetadataVarName is the variable name used in generated code to refer
|
||||
// to the compressed bytes of this descriptor. It is not exported, so it is only
|
||||
// valid inside the generated package.
|
||||
//
|
||||
// protoc-gen-go writes its own version of this file, but so does
|
||||
// protoc-gen-gogo - with a different name! PSRPC aims to be compatible with
|
||||
// both; the simplest way forward is to write the file descriptor again as
|
||||
// another variable that we control.
|
||||
func (t *psrpc) serviceMetadataVarName() string {
|
||||
return fmt.Sprintf("psrpcFileDescriptor%d", t.filesHandled)
|
||||
}
|
||||
|
||||
func (t *psrpc) generateFileDescriptor(file *descriptor.FileDescriptorProto) {
|
||||
// Copied straight off of protoc-gen-go, which trims out comments.
|
||||
pb := proto.Clone(file).(*descriptor.FileDescriptorProto)
|
||||
pb.SourceCodeInfo = nil
|
||||
|
||||
b, err := proto.Marshal(pb)
|
||||
if err != nil {
|
||||
gen.Fail(err.Error())
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
|
||||
_, _ = w.Write(b)
|
||||
_ = w.Close()
|
||||
b = buf.Bytes()
|
||||
|
||||
v := t.serviceMetadataVarName()
|
||||
t.P()
|
||||
t.P("var ", v, " = []byte{")
|
||||
t.P(" // ", fmt.Sprintf("%d", len(b)), " bytes of a gzipped FileDescriptorProto")
|
||||
for len(b) > 0 {
|
||||
n := 16
|
||||
if n > len(b) {
|
||||
n = len(b)
|
||||
}
|
||||
|
||||
s := ""
|
||||
for _, c := range b[:n] {
|
||||
s += fmt.Sprintf("0x%02x,", c)
|
||||
}
|
||||
t.P(` `, s)
|
||||
|
||||
b = b[n:]
|
||||
}
|
||||
t.P("}")
|
||||
}
|
||||
|
||||
func (t *psrpc) printComments(comments typemap.DefinitionComments) bool {
|
||||
text := strings.TrimSuffix(comments.Leading, "\n")
|
||||
if len(strings.TrimSpace(text)) == 0 {
|
||||
return false
|
||||
}
|
||||
split := strings.Split(text, "\n")
|
||||
for _, line := range split {
|
||||
t.P("// ", strings.TrimPrefix(line, " "))
|
||||
}
|
||||
return len(split) > 0
|
||||
}
|
||||
|
||||
// Given a protobuf name for a Message, return the Go name we will use for that
|
||||
// type, including its package prefix.
|
||||
func (t *psrpc) goTypeName(protoName string) string {
|
||||
def := t.reg.MessageDefinition(protoName)
|
||||
if def == nil {
|
||||
gen.Fail("could not find message for", protoName)
|
||||
}
|
||||
|
||||
var prefix string
|
||||
if pkg := t.goPackageName(def.File); pkg != t.genPkgName {
|
||||
prefix = pkg + "."
|
||||
}
|
||||
|
||||
var name string
|
||||
for _, parent := range def.Lineage() {
|
||||
name += stringutils.CamelCase(parent.Descriptor.GetName()) + "_"
|
||||
}
|
||||
name += stringutils.CamelCase(def.Descriptor.GetName())
|
||||
return prefix + name
|
||||
}
|
||||
|
||||
func (t *psrpc) goPackageName(file *descriptor.FileDescriptorProto) string {
|
||||
return t.fileToGoPackageName[file]
|
||||
}
|
||||
|
||||
func (t *psrpc) formattedOutput() string {
|
||||
// Reformat generated code.
|
||||
fset := token.NewFileSet()
|
||||
raw := t.output.Bytes()
|
||||
ast, err := parser.ParseFile(fset, "", raw, parser.ParseComments)
|
||||
if err != nil {
|
||||
// Print out the bad code with line numbers.
|
||||
// This should never happen in practice, but it can while changing generated code,
|
||||
// so consider this a debugging aid.
|
||||
var src bytes.Buffer
|
||||
s := bufio.NewScanner(bytes.NewReader(raw))
|
||||
for line := 1; s.Scan(); line++ {
|
||||
_, _ = fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes())
|
||||
}
|
||||
gen.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String())
|
||||
}
|
||||
|
||||
out := bytes.NewBuffer(nil)
|
||||
err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(out, fset, ast)
|
||||
if err != nil {
|
||||
gen.Fail("generated Go source code could not be reformatted:", err.Error())
|
||||
}
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func unexported(s string) string { return strings.ToLower(s[:1]) + s[1:] }
|
||||
|
||||
func serviceNameCamelCased(service *descriptor.ServiceDescriptorProto) string {
|
||||
return stringutils.CamelCase(service.GetName())
|
||||
}
|
||||
|
||||
func serviceStruct(service *descriptor.ServiceDescriptorProto) string {
|
||||
return unexported(serviceNameCamelCased(service)) + "Server"
|
||||
}
|
||||
|
||||
func methodNameCamelCased(method *descriptor.MethodDescriptorProto) string {
|
||||
return stringutils.CamelCase(method.GetName())
|
||||
}
|
||||
|
||||
func fileDescSliceContains(slice []*descriptor.FileDescriptorProto, f *descriptor.FileDescriptorProto) bool {
|
||||
for _, sf := range slice {
|
||||
if f == sf {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
plugin "google.golang.org/protobuf/types/pluginpb"
|
||||
)
|
||||
|
||||
func TestGenerateParseCommandLineParamsError(t *testing.T) {
|
||||
if os.Getenv("BE_CRASHER") == "1" {
|
||||
g := &psrpc{}
|
||||
g.Generate(&plugin.CodeGeneratorRequest{
|
||||
Parameter: proto.String("invalid"),
|
||||
})
|
||||
return
|
||||
}
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestGenerateParseCommandLineParamsError")
|
||||
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
|
||||
err := cmd.Run()
|
||||
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||
return
|
||||
}
|
||||
t.Fatalf("process ran with err %v, want exit status 1", err)
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
|
||||
"github.com/livekit/psrpc/internal/gen/stringutils"
|
||||
)
|
||||
|
||||
// goPackageOption interprets the file's go_package option.
|
||||
// If there is no go_package, it returns ("", "", false).
|
||||
// If there's a simple name, it returns ("", pkg, true).
|
||||
// If the option implies an import path, it returns (impPath, pkg, true).
|
||||
func goPackageOption(f *descriptor.FileDescriptorProto) (impPath, pkg string, ok bool) {
|
||||
pkg = f.GetOptions().GetGoPackage()
|
||||
if pkg == "" {
|
||||
return "", "", false
|
||||
}
|
||||
if bits := strings.Split(pkg, ";"); len(bits) == 2 {
|
||||
return bits[0], bits[1], true
|
||||
}
|
||||
// The presence of a slash implies there's an import path.
|
||||
slash := strings.LastIndex(pkg, "/")
|
||||
if slash < 0 {
|
||||
return "", pkg, true
|
||||
}
|
||||
impPath, pkg = pkg, pkg[slash+1:]
|
||||
// A semicolon-delimited suffix overrides the package name.
|
||||
sc := strings.IndexByte(impPath, ';')
|
||||
if sc < 0 {
|
||||
return impPath, pkg, true
|
||||
}
|
||||
impPath, pkg = impPath[:sc], impPath[sc+1:]
|
||||
return impPath, pkg, true
|
||||
}
|
||||
|
||||
// goPackageName returns the Go package name to use in the generated Go file.
|
||||
// The result explicitly reports whether the name came from an option go_package
|
||||
// statement. If explicit is false, the name was derived from the protocol
|
||||
// buffer's package statement or the input file name.
|
||||
func goPackageName(f *descriptor.FileDescriptorProto) (name string, explicit bool) {
|
||||
// Does the file have a "go_package" option?
|
||||
if _, pkg, ok := goPackageOption(f); ok {
|
||||
return pkg, true
|
||||
}
|
||||
|
||||
// Does the file have a package clause?
|
||||
if pkg := f.GetPackage(); pkg != "" {
|
||||
return pkg, false
|
||||
}
|
||||
// Use the file base name.
|
||||
return stringutils.BaseName(f.GetName()), false
|
||||
}
|
||||
|
||||
// goFileName returns the output name for the generated Go file.
|
||||
func (t *psrpc) goFileName(f *descriptor.FileDescriptorProto) string {
|
||||
name := *f.Name // proto file name
|
||||
if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
|
||||
name = name[:len(name)-len(ext)] // remove extension
|
||||
}
|
||||
name += ".psrpc.go" // add psrpc extension
|
||||
|
||||
// with paths=source_relative, the directory is the same as the proto file
|
||||
if t.sourceRelativePaths {
|
||||
return name
|
||||
}
|
||||
// otherwise, the directory is taken from the option go_package
|
||||
if impPath, _, ok := goPackageOption(f); ok && impPath != "" {
|
||||
if t.modulePrefix != "" {
|
||||
impPath = strings.TrimPrefix(strings.TrimPrefix(impPath, t.modulePrefix), "/")
|
||||
}
|
||||
|
||||
// Replace the existing dirname with the import path from go_package
|
||||
_, name = path.Split(name)
|
||||
name = path.Join(impPath, name)
|
||||
return name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func parseGoPackageOption(v string) (importPath, packageName string) {
|
||||
// Allowed formats:
|
||||
// option go_package = "foo";
|
||||
// option go_package = "github.com/example/foo";
|
||||
// option go_package = "github.com/example/foo;bar";
|
||||
|
||||
semicolonPos := strings.Index(v, ";")
|
||||
if semicolonPos > -1 {
|
||||
importPath = v[:semicolonPos]
|
||||
packageName = v[semicolonPos+1:]
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(v, "/") {
|
||||
importPath = v
|
||||
_, packageName = path.Split(v)
|
||||
return
|
||||
}
|
||||
|
||||
importPath = ""
|
||||
packageName = v
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
descriptor "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
func TestParseGoPackageOption(t *testing.T) {
|
||||
testcase := func(in, wantImport, wantPkg string) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
haveImport, havePkg := parseGoPackageOption(in)
|
||||
if haveImport != wantImport {
|
||||
t.Errorf("wrong importPath, have=%q want=%q", haveImport, wantImport)
|
||||
}
|
||||
if havePkg != wantPkg {
|
||||
t.Errorf("wrong packageName, have=%q want=%q", havePkg, wantPkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("empty string", testcase("", "", ""))
|
||||
t.Run("bare package", testcase("foo", "", "foo"))
|
||||
t.Run("full import", testcase("github.com/example/foo", "github.com/example/foo", "foo"))
|
||||
t.Run("full import with override",
|
||||
testcase("github.com/example/foo;bar", "github.com/example/foo", "bar"))
|
||||
t.Run("non dotted import with package", testcase("foo;bar", "foo", "bar"))
|
||||
}
|
||||
|
||||
func TestGoPackageOption(t *testing.T) {
|
||||
testcase := func(in, wantImport, wantPkg string, wantOK bool) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
haveImport, havePkg, haveOK := goPackageOption(&descriptor.FileDescriptorProto{
|
||||
Options: &descriptor.FileOptions{
|
||||
GoPackage: &in,
|
||||
},
|
||||
})
|
||||
if wantOK != haveOK {
|
||||
t.Errorf("wrong ok, have=%t want=%t", haveOK, wantOK)
|
||||
}
|
||||
if haveImport != wantImport {
|
||||
t.Errorf("wrong importPath, have=%q want=%q", haveImport, wantImport)
|
||||
}
|
||||
if havePkg != wantPkg {
|
||||
t.Errorf("wrong packageName, have=%q want=%q", havePkg, wantPkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("empty string", testcase("", "", "", false))
|
||||
t.Run("bare package", testcase("foo", "", "foo", true))
|
||||
t.Run("full import", testcase("github.com/example/foo", "github.com/example/foo", "foo", true))
|
||||
t.Run("full import with override",
|
||||
testcase("github.com/example/foo;bar", "github.com/example/foo", "bar", true))
|
||||
t.Run("non dotted import with package", testcase("foo;bar", "foo", "bar", true))
|
||||
}
|
||||
|
||||
func TestGoFileName(t *testing.T) {
|
||||
testcase := func(srcrelpaths bool, modprefix, fname, gopkg, wantName string) func(t2 *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
f := &descriptor.FileDescriptorProto{
|
||||
Name: &fname,
|
||||
Options: &descriptor.FileOptions{
|
||||
GoPackage: &gopkg,
|
||||
},
|
||||
}
|
||||
|
||||
tw := &psrpc{
|
||||
sourceRelativePaths: srcrelpaths,
|
||||
modulePrefix: modprefix,
|
||||
}
|
||||
|
||||
if name := tw.goFileName(f); name != wantName {
|
||||
t.Errorf("wrong goFileName, have=%q want=%q", name, wantName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("paths=source_relative",
|
||||
testcase(true, "",
|
||||
"rpc/v1/service.proto", "example.com/module/package/rpc/v1",
|
||||
"rpc/v1/service.psrpc.go"))
|
||||
|
||||
t.Run("paths=import,module=example.com/module/package",
|
||||
testcase(false, "example.com/module/package",
|
||||
"rpc/v1/service.proto", "example.com/module/package/rpc/v1",
|
||||
"rpc/v1/service.psrpc.go"))
|
||||
|
||||
t.Run("paths=import,module=example.com/module/package/",
|
||||
testcase(false, "example.com/module/package/",
|
||||
"rpc/v1/service.proto", "example.com/module/package/rpc/v1",
|
||||
"rpc/v1/service.psrpc.go"))
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
||||
// use this file except in compliance with the License. A copy of the License is
|
||||
// located at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// or in the "license" file accompanying this file. This file is distributed on
|
||||
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
// express or implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/livekit/psrpc/internal/gen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
versionFlag := flag.Bool("version", false, "print version and exit")
|
||||
flag.Parse()
|
||||
if *versionFlag {
|
||||
fmt.Println(gen.Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
g := newGenerator()
|
||||
gen.Main(g)
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.21.5
|
||||
// source: options.proto
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||
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 Options struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// For RPCs, each client request will receive a response from every server.
|
||||
// For subscriptions, every client will receive every update.
|
||||
Multi bool `protobuf:"varint,1,opt,name=multi,proto3" json:"multi,omitempty"`
|
||||
// This method is a pub/sub.
|
||||
Subscription bool `protobuf:"varint,2,opt,name=subscription,proto3" json:"subscription,omitempty"`
|
||||
// This method uses topics.
|
||||
Topics bool `protobuf:"varint,3,opt,name=topics,proto3" json:"topics,omitempty"`
|
||||
// Your service will supply an affinity function for handler selection.
|
||||
AffinityFunc bool `protobuf:"varint,4,opt,name=affinity_func,json=affinityFunc,proto3" json:"affinity_func,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Options) Reset() {
|
||||
*x = Options{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_options_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Options) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Options) ProtoMessage() {}
|
||||
|
||||
func (x *Options) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_options_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 Options.ProtoReflect.Descriptor instead.
|
||||
func (*Options) Descriptor() ([]byte, []int) {
|
||||
return file_options_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Options) GetMulti() bool {
|
||||
if x != nil {
|
||||
return x.Multi
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Options) GetSubscription() bool {
|
||||
if x != nil {
|
||||
return x.Subscription
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Options) GetTopics() bool {
|
||||
if x != nil {
|
||||
return x.Topics
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Options) GetAffinityFunc() bool {
|
||||
if x != nil {
|
||||
return x.AffinityFunc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var file_options_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MethodOptions)(nil),
|
||||
ExtensionType: (*Options)(nil),
|
||||
Field: 2198,
|
||||
Name: "psrpc.options",
|
||||
Tag: "bytes,2198,opt,name=options",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.MethodOptions.
|
||||
var (
|
||||
// optional psrpc.Options options = 2198;
|
||||
E_Options = &file_options_proto_extTypes[0]
|
||||
)
|
||||
|
||||
var File_options_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_options_proto_rawDesc = []byte{
|
||||
0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||
0x05, 0x70, 0x73, 0x72, 0x70, 0x63, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x01, 0x0a, 0x07, 0x4f, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x75,
|
||||
0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
|
||||
0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x69, 0x6e, 0x69,
|
||||
0x74, 0x79, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61,
|
||||
0x66, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x46, 0x75, 0x6e, 0x63, 0x3a, 0x4c, 0x0a, 0x07, 0x6f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x96, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f,
|
||||
0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e,
|
||||
0x2d, 0x70, 0x73, 0x72, 0x70, 0x63, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_options_proto_rawDescOnce sync.Once
|
||||
file_options_proto_rawDescData = file_options_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_options_proto_rawDescGZIP() []byte {
|
||||
file_options_proto_rawDescOnce.Do(func() {
|
||||
file_options_proto_rawDescData = protoimpl.X.CompressGZIP(file_options_proto_rawDescData)
|
||||
})
|
||||
return file_options_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_options_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_options_proto_goTypes = []interface{}{
|
||||
(*Options)(nil), // 0: psrpc.Options
|
||||
(*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions
|
||||
}
|
||||
var file_options_proto_depIdxs = []int32{
|
||||
1, // 0: psrpc.options:extendee -> google.protobuf.MethodOptions
|
||||
0, // 1: psrpc.options:type_name -> psrpc.Options
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
1, // [1:2] is the sub-list for extension type_name
|
||||
0, // [0:1] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_options_proto_init() }
|
||||
func file_options_proto_init() {
|
||||
if File_options_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_options_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Options); 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_options_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 1,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_options_proto_goTypes,
|
||||
DependencyIndexes: file_options_proto_depIdxs,
|
||||
MessageInfos: file_options_proto_msgTypes,
|
||||
ExtensionInfos: file_options_proto_extTypes,
|
||||
}.Build()
|
||||
File_options_proto = out.File
|
||||
file_options_proto_rawDesc = nil
|
||||
file_options_proto_goTypes = nil
|
||||
file_options_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package psrpc;
|
||||
option go_package = "github.com/livekit/psrpc/protoc-gen-psrpc/options";
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
extend google.protobuf.MethodOptions {
|
||||
optional Options options = 2198;
|
||||
}
|
||||
|
||||
message Options {
|
||||
// For RPCs, each client request will receive a response from every server.
|
||||
// For subscriptions, every client will receive every update.
|
||||
bool multi = 1;
|
||||
|
||||
// This method is a pub/sub.
|
||||
bool subscription = 2;
|
||||
|
||||
// This method uses topics.
|
||||
bool topics = 3;
|
||||
|
||||
// Your service will supply an affinity function for handler selection.
|
||||
bool affinity_func = 4;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user