Showing preview only (295K chars total). Download the full file or copy to clipboard to get everything.
Repository: rapidloop/nrpc
Branch: master
Commit: 8f47f6a864d1
Files: 42
Total size: 280.6 KB
Directory structure:
gitextract_mwgdltlr/
├── .gitignore
├── .travis.yml
├── AUTHORS
├── LICENSE
├── README.md
├── alloptions_test.go
├── examples/
│ ├── alloptions/
│ │ ├── alloptions.nrpc.go
│ │ ├── alloptions.pb.go
│ │ ├── alloptions.proto
│ │ ├── alloptions_test.go
│ │ ├── main.go
│ │ └── testrunner_test.go
│ ├── helloworld/
│ │ ├── greeter_client/
│ │ │ └── main.go
│ │ ├── greeter_server/
│ │ │ ├── main.go
│ │ │ ├── main_test.go
│ │ │ └── testrunner_test.go
│ │ └── helloworld/
│ │ ├── helloworld.go
│ │ ├── helloworld.nrpc.go
│ │ ├── helloworld.pb.go
│ │ └── helloworld.proto
│ ├── metrics_helloworld/
│ │ ├── helloworld/
│ │ │ ├── helloworld.go
│ │ │ ├── helloworld.nrpc.go
│ │ │ ├── helloworld.pb.go
│ │ │ └── helloworld.proto
│ │ ├── metrics_greeter_client/
│ │ │ └── main.go
│ │ └── metrics_greeter_server/
│ │ └── main.go
│ └── nooption/
│ ├── nooption.go
│ ├── nooption.nrpc.go
│ ├── nooption.pb.go
│ └── nooption.proto
├── go.mod
├── go.sum
├── helloworld_test.go
├── nrpc.go
├── nrpc.pb.go
├── nrpc.proto
├── nrpc_test.go
├── nrpc_test.proto
├── nrpcpb_test.go
├── protoc-gen-nrpc/
│ ├── main.go
│ └── tmpl.go
└── testrunner_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
examples/helloworld/greeter_client/greeter_client
examples/helloworld/greeter_server/greeter_server
examples/alloptions/alloptions
================================================
FILE: .travis.yml
================================================
language: go
go:
- 1.13
before_script:
- curl -sSL https://github.com/google/protobuf/releases/download/v3.12.1/protoc-3.12.1-linux-x86_64.zip -o protoc.zip
- sudo unzip -d /usr/local protoc.zip
- sudo chmod a+x /usr/local/bin/protoc
- sudo chmod -R a+rx /usr/local/include/google
- go get google.golang.org/protobuf/cmd/protoc-gen-go
- go install google.golang.org/protobuf/cmd/protoc-gen-go
script:
- go test ./...
================================================
FILE: AUTHORS
================================================
RapidLoop, Inc.
Christophe de Vienne, Orus.io
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License 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.
================================================
FILE: README.md
================================================
# nRPC
[](https://travis-ci.org/nats-rpc/nrpc)
nRPC is an RPC framework like [gRPC](https://grpc.io/), but for
[NATS](https://nats.io/).
It can generate a Go client and server from the same .proto file that you'd
use to generate gRPC clients and servers. The server is generated as a NATS
[MsgHandler](https://godoc.org/github.com/nats-io/nats.go#MsgHandler).
The [Specifications](https://github.com/nats-rpc/nrpc/wiki/Specifications)
describes how nRPC translates protobuf services and methods into NATS patterns.
## Why NATS?
Doing RPC over NATS'
[request-response model](http://nats.io/documentation/concepts/nats-req-rep/)
has some advantages over a gRPC model:
- **Minimal service discovery**: The clients and servers only need to know the
endpoints of a NATS cluster. The clients do not need to discover the
endpoints of individual services they depend on.
- **Load balancing without load balancers**: Stateless microservices can be
hosted redundantly and connected to the same NATS cluster. The incoming
requests can then be random-routed among these using NATS
[queueing](http://nats.io/documentation/concepts/nats-queueing/). There is
no need to setup a (high availability) load balancer per microservice.
The lunch is not always free, however. At scale, the NATS cluster itself can
become a bottleneck. Features of gRPC like streaming and advanced auth are not
available.
Still, NATS - and nRPC - offer much lower operational complexity if your
scale and requirements fit.
At RapidLoop, we use this model for our [OpsDash](https://www.opsdash.com)
SaaS product in production and are quite happy with it. nRPC is the third
iteration of an internal library.
## Overview
nRPC comes with a protobuf compiler plugin `protoc-gen-nrpc`, which generates
Go code from a .proto file.
Given a .proto file like [helloworld.proto](https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto), the usage is like this:
```
$ ls
helloworld.proto
$ protoc --go_out=. --nrpc_out=. helloworld.proto
$ ls
helloworld.nrpc.go helloworld.pb.go helloworld.proto
```
The .pb.go file, which contains the definitions for the message classes, is
generated by the standard Go plugin for protoc. The .nrpc.go file, which
contains the definitions for a client, a server interface, and a NATS handler
is generated by the nRPC plugin.
Have a look at the generated and example files:
- the service definition [helloworld.proto](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/helloworld/helloworld.proto)
- the generated nrpc go file [helloworld.nrpc.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/helloworld/helloworld.nrpc.go)
- an example server [greeter_server/main.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/greeter_server/main.go)
- an example client [greeter_client/main.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/greeter_client/main.go)
### How It Works
The .proto file defines messages (like HelloRequest and HelloReply in the
example) and services (Greeter) that have methods (SayHello).
The messages are generated as Go structs by the regular Go protobuf compiler
plugin and gets written out to \*.pb.go files.
For the rest, nRPC generates three logical pieces.
The first is a Go interface type (GreeterServer) which your actual
microservice code should implement:
```
// This is what is contained in the .proto file
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// This is the generated interface which you've to implement
type GreeterServer interface {
SayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)
}
```
The second is a client (GreeterClient struct). This struct has
methods with appropriate types, that correspond to the service definition. The
client code will marshal and wrap the request object (HelloRequest) and do a
NATS `Request`.
```
// The client is associated with a NATS connection.
func NewGreeterClient(nc *nats.Conn) *GreeterClient {...}
// And has properly typed methods that will marshal and perform a NATS request.
func (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {...}
```
The third and final piece is the handler (GreeterHandler). Given a NATS
connection and a server implementation, it can accept NATS requests in the
format sent by the client above. It should be installed as a message handler for
a particular NATS subject (defaults to the name of the service) using the
NATS Subscribe() or QueueSubscribe() methods. It will invoke the appropriate
method of the GreeterServer interface upon receiving the appropriate request.
```
// A handler is associated with a NATS connection and a server implementation.
func NewGreeterHandler(ctx context.Context, nc *nats.Conn, s GreeterServer) *GreeterHandler {...}
// It has a method that can (should) be used as a NATS message handler.
func (h *GreeterHandler) Handler(msg *nats.Msg) {...}
```
Standing up a microservice involves:
- writing the .proto service definition file
- generating the \*.pb.go and \*.nrpc.go files
- implementing the server interface
- writing a main app that will connect to NATS and start the handler ([see
example](https://github.com/nats-rpc/nrpc/blob/master/examples/helloworld/greeter_server/main.go))
To call the service:
- import the package that contains the generated *.nrpc.go files
- in the client code, connect to NATS
- create a Caller object and call the methods as necessary ([see example](https://github.com/nats-rpc/nrpc/blob/master/examples/helloworld/greeter_client/main.go))
## Features
The following wiki pages describe nRPC features in more detail:
- [Load Balancing](https://github.com/nats-rpc/nrpc/wiki/Load-Balancing)
- [Metrics Instrumentation](https://github.com/nats-rpc/nrpc/wiki/Metrics-Instrumentation)
using Prometheus
## Installation
nRPC needs Go 1.11 or higher. $GOPATH/bin needs to be in $PATH for the protoc
invocation to work. To generate code, you need the protobuf compiler (which
you can install from [here](https://github.com/google/protobuf/releases))
and the nRPC protoc plugin.
To install the nRPC protoc plugin:
```
$ go install github.com/nats-rpc/nrpc/protoc-gen-nrpc@latest
```
To build and run the example greeter_server:
```
$ go install github.com/nats-rpc/nrpc/examples/helloworld/greeter_server@latest
$ greeter_server
server is running, ^C quits.
```
To build and run the example greeter_client:
```
$ go install github.com/nats-rpc/nrpc/examples/helloworld/greeter_client@latest
$ greeter_client
Greeting: Hello world
$
```
## Documentation
To learn more about describing gRPC services using .proto files, see [here](https://grpc.io/docs/guides/concepts.html).
To learn more about NATS, start with their [website](https://nats.io/). To
learn more about nRPC, um, read the source code.
## Status
nRPC is in alpha. This means that it will work, but APIs may change without
notice.
Currently there is support only for Go clients and servers.
Built by RapidLoop. Released under Apache 2.0 license.
================================================
FILE: alloptions_test.go
================================================
package nrpc
import (
//"bytes"
//"os"
"os/exec"
"testing"
//"time"
)
func TestAllOptionsExample(t *testing.T) {
// make sure protoc-gen-nrpc is up to date
installGenRPC := exec.Command("go", "install", "./protoc-gen-nrpc")
if out, err := installGenRPC.CombinedOutput(); err != nil {
t.Fatal("Install protoc-gen-nrpc failed", err, ":\n", string(out))
}
// generate the sources
generate := exec.Command("go", "generate", "./examples/alloptions")
if out, err := generate.CombinedOutput(); err != nil {
t.Fatal("Generate failed", err, ":\n", string(out))
}
// build
build := exec.Command("go", "build",
"-o", "./examples/alloptions/alloptions",
"./examples/alloptions")
if out, err := build.CombinedOutput(); err != nil {
t.Fatal("Buid failed", err, string(out))
}
}
================================================
FILE: examples/alloptions/alloptions.nrpc.go
================================================
// This code was autogenerated from alloptions.proto, do not edit.
package main
import (
"context"
"log"
"time"
"google.golang.org/protobuf/proto"
"github.com/nats-io/nats.go"
github_com_nats_rpc_nrpc "github.com/nats-rpc/nrpc"
"github.com/nats-rpc/nrpc"
)
// SvcCustomSubjectServer is the interface that providers of the service
// SvcCustomSubject should implement.
type SvcCustomSubjectServer interface {
MtSimpleReply(ctx context.Context, req *StringArg) (*SimpleStringReply, error)
MtVoidReply(ctx context.Context, req *StringArg) (error)
MtStreamedReply(ctx context.Context, req *StringArg, pushRep func(*SimpleStringReply)) (error)
MtVoidReqStreamedReply(ctx context.Context, pushRep func(*SimpleStringReply)) (error)
}
// SvcCustomSubjectHandler provides a NATS subscription handler that can serve a
// subscription using a given SvcCustomSubjectServer implementation.
type SvcCustomSubjectHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server SvcCustomSubjectServer
encodings []string
}
func NewSvcCustomSubjectHandler(ctx context.Context, nc nrpc.NatsConn, s SvcCustomSubjectServer) *SvcCustomSubjectHandler {
return &SvcCustomSubjectHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewSvcCustomSubjectConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s SvcCustomSubjectServer) *SvcCustomSubjectHandler {
return &SvcCustomSubjectHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *SvcCustomSubjectHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *SvcCustomSubjectHandler) Subject() string {
return "root.*.custom_subject.>"
}
func (h *SvcCustomSubjectHandler) MtNoRequestPublish(pkginstance string, msg *SimpleStringReply) error {
for _, encoding := range h.encodings {
rawMsg, err := nrpc.Marshal(encoding, msg)
if err != nil {
log.Printf("SvcCustomSubjectHandler.MtNoRequestPublish: error marshaling the message: %s", err)
return err
}
subject := "root." + pkginstance + "."+ "custom_subject."+ "mtnorequest"
if encoding != "protobuf" {
subject += "." + encoding
}
if err := h.nc.Publish(subject, rawMsg); err != nil {
return err
}
}
return nil
}
func (h *SvcCustomSubjectHandler) Handler(msg *nats.Msg) {
var ctx context.Context
if h.workers != nil {
ctx = h.workers.Context
} else {
ctx = h.ctx
}
request := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)
// extract method name & encoding from subject
pkgParams, _, name, tail, err := nrpc.ParseSubject(
"root", 1, "custom_subject", 0, msg.Subject)
if err != nil {
log.Printf("SvcCustomSubjectHanlder: SvcCustomSubject subject parsing failed: %v", err)
return
}
request.MethodName = name
request.SubjectTail = tail
request.SetPackageParam("instance", pkgParams[0])
// call handler and form response
var immediateError *nrpc.Error
switch name {
case "mt_simple_reply":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("MtSimpleReplyHanlder: MtSimpleReply subject parsing failed: %v", err)
break
}
var req StringArg
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtSimpleReplyHandler: MtSimpleReply request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
innerResp, err := h.server.MtSimpleReply(ctx, &req)
if err != nil {
return nil, err
}
return innerResp, err
}
}
case "mtvoidreply":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("MtVoidReplyHanlder: MtVoidReply subject parsing failed: %v", err)
break
}
var req StringArg
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtVoidReplyHandler: MtVoidReply request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
var innerResp = &nrpc.Void{}
err := h.server.MtVoidReply(ctx, &req)
if err != nil {
return nil, err
}
return innerResp, err
}
}
case "mtnorequest":
// MtNoRequest is a no-request method. Ignore it.
return
case "mtstreamedreply":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("MtStreamedReplyHanlder: MtStreamedReply subject parsing failed: %v", err)
break
}
var req StringArg
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtStreamedReplyHandler: MtStreamedReply request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.EnableStreamedReply()
request.Handler = func(ctx context.Context)(proto.Message, error){
err := h.server.MtStreamedReply(ctx, &req, func(rep *SimpleStringReply){
request.SendStreamReply(rep)
})
return nil, err
}
}
case "mtvoidreqstreamedreply":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("MtVoidReqStreamedReplyHanlder: MtVoidReqStreamedReply subject parsing failed: %v", err)
break
}
var req github_com_nats_rpc_nrpc.Void
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtVoidReqStreamedReplyHandler: MtVoidReqStreamedReply request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.EnableStreamedReply()
request.Handler = func(ctx context.Context)(proto.Message, error){
err := h.server.MtVoidReqStreamedReply(ctx, func(rep *SimpleStringReply){
request.SendStreamReply(rep)
})
return nil, err
}
}
default:
log.Printf("SvcCustomSubjectHandler: unknown name %q", name)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "unknown name: " + name,
}
}
if immediateError == nil {
if h.workers != nil {
// Try queuing the request
if err := h.workers.QueueRequest(request); err != nil {
log.Printf("nrpc: Error queuing the request: %s", err)
}
} else {
// Run the handler synchronously
request.RunAndReply()
}
}
if immediateError != nil {
if err := request.SendReply(nil, immediateError); err != nil {
log.Printf("SvcCustomSubjectHandler: SvcCustomSubject handler failed to publish the response: %s", err)
}
} else {
}
}
type SvcCustomSubjectClient struct {
nc nrpc.NatsConn
PkgSubject string
PkgParaminstance string
Subject string
Encoding string
Timeout time.Duration
}
func NewSvcCustomSubjectClient(nc nrpc.NatsConn, pkgParaminstance string) *SvcCustomSubjectClient {
return &SvcCustomSubjectClient{
nc: nc,
PkgSubject: "root",
PkgParaminstance: pkgParaminstance,
Subject: "custom_subject",
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *SvcCustomSubjectClient) MtSimpleReply(req *StringArg) (*SimpleStringReply, error) {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mt_simple_reply"
// call
var resp = SimpleStringReply{}
if err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {
return nil, err
}
return &resp, nil
}
func (c *SvcCustomSubjectClient) MtSimpleReplyPoll(req *StringArg,maxreplies int, cb func (*SimpleStringReply) error,
) (error) {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mt_simple_reply"
var resp SimpleStringReply
err := nrpc.Poll(req, &resp, c.nc, subject, c.Encoding, c.Timeout, maxreplies,
func() error {
return cb(&resp)
},
)
if err != nil {
return err
}
return nil
}
func (c *SvcCustomSubjectClient) MtVoidReply(req *StringArg) (error) {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mtvoidreply"
// call
var resp = github_com_nats_rpc_nrpc.Void{}
if err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {
return err
}
return nil
}
func (c *SvcCustomSubjectClient) MtNoRequestSubject(
) string {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mtnorequest"
if c.Encoding != "protobuf" {
subject += "." + c.Encoding
}
return subject
}
type SvcCustomSubjectMtNoRequestSubscription struct {
*nats.Subscription
encoding string
}
func (s *SvcCustomSubjectMtNoRequestSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {
msg, err := s.Subscription.NextMsg(timeout)
if err != nil {
return
}
err = nrpc.Unmarshal(s.encoding, msg.Data, &next)
return
}
func (c *SvcCustomSubjectClient) MtNoRequestSubscribeSync(
) (sub *SvcCustomSubjectMtNoRequestSubscription, err error) {
subject := c.MtNoRequestSubject(
)
natsSub, err := c.nc.SubscribeSync(subject)
if err != nil {
return
}
sub = &SvcCustomSubjectMtNoRequestSubscription{natsSub, c.Encoding}
return
}
func (c *SvcCustomSubjectClient) MtNoRequestSubscribe(
handler func (*SimpleStringReply),
) (sub *nats.Subscription, err error) {
subject := c.MtNoRequestSubject(
)
sub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){
var pmsg SimpleStringReply
err := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)
if err != nil {
log.Printf("SvcCustomSubjectClient.MtNoRequestSubscribe: Error decoding, %s", err)
return
}
handler(&pmsg)
})
return
}
func (c *SvcCustomSubjectClient) MtNoRequestSubscribeChan(
) (<-chan *SimpleStringReply, *nats.Subscription, error) {
ch := make(chan *SimpleStringReply)
sub, err := c.MtNoRequestSubscribe(func (msg *SimpleStringReply) {
ch <- msg
})
return ch, sub, err
}
func (c *SvcCustomSubjectClient) MtStreamedReply(
ctx context.Context,
req *StringArg,
cb func (context.Context, *SimpleStringReply),
) error {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mtstreamedreply"
sub, err := nrpc.StreamCall(ctx, c.nc, subject, req, c.Encoding, c.Timeout)
if err != nil {
return err
}
var res SimpleStringReply
for {
err = sub.Next(&res)
if err != nil {
break
}
cb(ctx, &res)
}
if err == nrpc.ErrEOS {
err = nil
}
return err
}
func (c *SvcCustomSubjectClient) MtVoidReqStreamedReply(
ctx context.Context,
cb func (context.Context, *SimpleStringReply),
) error {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mtvoidreqstreamedreply"
sub, err := nrpc.StreamCall(ctx, c.nc, subject, &nrpc.Void{}, c.Encoding, c.Timeout)
if err != nil {
return err
}
var res SimpleStringReply
for {
err = sub.Next(&res)
if err != nil {
break
}
cb(ctx, &res)
}
if err == nrpc.ErrEOS {
err = nil
}
return err
}
// SvcSubjectParamsServer is the interface that providers of the service
// SvcSubjectParams should implement.
type SvcSubjectParamsServer interface {
MtWithSubjectParams(ctx context.Context, mp1 string, mp2 string) (*SimpleStringReply, error)
MtStreamedReplyWithSubjectParams(ctx context.Context, mp1 string, mp2 string, pushRep func(*SimpleStringReply)) (error)
MtNoReply(ctx context.Context)
}
// SvcSubjectParamsHandler provides a NATS subscription handler that can serve a
// subscription using a given SvcSubjectParamsServer implementation.
type SvcSubjectParamsHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server SvcSubjectParamsServer
encodings []string
}
func NewSvcSubjectParamsHandler(ctx context.Context, nc nrpc.NatsConn, s SvcSubjectParamsServer) *SvcSubjectParamsHandler {
return &SvcSubjectParamsHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewSvcSubjectParamsConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s SvcSubjectParamsServer) *SvcSubjectParamsHandler {
return &SvcSubjectParamsHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *SvcSubjectParamsHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *SvcSubjectParamsHandler) Subject() string {
return "root.*.svcsubjectparams.*.>"
}
func (h *SvcSubjectParamsHandler) MtNoRequestWParamsPublish(pkginstance string, svcclientid string, mtmp1 string, msg *SimpleStringReply) error {
for _, encoding := range h.encodings {
rawMsg, err := nrpc.Marshal(encoding, msg)
if err != nil {
log.Printf("SvcSubjectParamsHandler.MtNoRequestWParamsPublish: error marshaling the message: %s", err)
return err
}
subject := "root." + pkginstance + "."+ "svcsubjectparams." + svcclientid + "."+ "mtnorequestwparams" + "." + mtmp1
if encoding != "protobuf" {
subject += "." + encoding
}
if err := h.nc.Publish(subject, rawMsg); err != nil {
return err
}
}
return nil
}
func (h *SvcSubjectParamsHandler) Handler(msg *nats.Msg) {
var ctx context.Context
if h.workers != nil {
ctx = h.workers.Context
} else {
ctx = h.ctx
}
request := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)
// extract method name & encoding from subject
pkgParams, svcParams, name, tail, err := nrpc.ParseSubject(
"root", 1, "svcsubjectparams", 1, msg.Subject)
if err != nil {
log.Printf("SvcSubjectParamsHanlder: SvcSubjectParams subject parsing failed: %v", err)
return
}
request.MethodName = name
request.SubjectTail = tail
request.SetPackageParam("instance", pkgParams[0])
request.SetServiceParam("clientid", svcParams[0])
// call handler and form response
var immediateError *nrpc.Error
switch name {
case "mtwithsubjectparams":
var mtParams []string
mtParams, request.Encoding, err = nrpc.ParseSubjectTail(2, request.SubjectTail)
if err != nil {
log.Printf("MtWithSubjectParamsHanlder: MtWithSubjectParams subject parsing failed: %v", err)
break
}
var req github_com_nats_rpc_nrpc.Void
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtWithSubjectParamsHandler: MtWithSubjectParams request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
innerResp, err := h.server.MtWithSubjectParams(ctx, mtParams[0], mtParams[1])
if err != nil {
return nil, err
}
return innerResp, err
}
}
case "mtstreamedreplywithsubjectparams":
var mtParams []string
mtParams, request.Encoding, err = nrpc.ParseSubjectTail(2, request.SubjectTail)
if err != nil {
log.Printf("MtStreamedReplyWithSubjectParamsHanlder: MtStreamedReplyWithSubjectParams subject parsing failed: %v", err)
break
}
var req github_com_nats_rpc_nrpc.Void
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtStreamedReplyWithSubjectParamsHandler: MtStreamedReplyWithSubjectParams request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.EnableStreamedReply()
request.Handler = func(ctx context.Context)(proto.Message, error){
err := h.server.MtStreamedReplyWithSubjectParams(ctx, mtParams[0], mtParams[1], func(rep *SimpleStringReply){
request.SendStreamReply(rep)
})
return nil, err
}
}
case "mtnoreply":
request.NoReply = true
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("MtNoReplyHanlder: MtNoReply subject parsing failed: %v", err)
break
}
var req github_com_nats_rpc_nrpc.Void
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("MtNoReplyHandler: MtNoReply request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){var innerResp = &nrpc.NoReply{}
h.server.MtNoReply(ctx)
if err != nil {
return nil, err
}
return innerResp, err
}
}
case "mtnorequestwparams":
// MtNoRequestWParams is a no-request method. Ignore it.
return
default:
log.Printf("SvcSubjectParamsHandler: unknown name %q", name)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "unknown name: " + name,
}
}
if immediateError == nil {
if h.workers != nil {
// Try queuing the request
if err := h.workers.QueueRequest(request); err != nil {
log.Printf("nrpc: Error queuing the request: %s", err)
}
} else {
// Run the handler synchronously
request.RunAndReply()
}
}
if immediateError != nil {
if err := request.SendReply(nil, immediateError); err != nil {
log.Printf("SvcSubjectParamsHandler: SvcSubjectParams handler failed to publish the response: %s", err)
}
} else {
}
}
type SvcSubjectParamsClient struct {
nc nrpc.NatsConn
PkgSubject string
PkgParaminstance string
Subject string
SvcParamclientid string
Encoding string
Timeout time.Duration
}
func NewSvcSubjectParamsClient(nc nrpc.NatsConn, pkgParaminstance string, svcParamclientid string) *SvcSubjectParamsClient {
return &SvcSubjectParamsClient{
nc: nc,
PkgSubject: "root",
PkgParaminstance: pkgParaminstance,
Subject: "svcsubjectparams",
SvcParamclientid: svcParamclientid,
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *SvcSubjectParamsClient) MtWithSubjectParams(mp1 string, mp2 string, ) (*SimpleStringReply, error) {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + c.SvcParamclientid + "." + "mtwithsubjectparams" + "." + mp1 + "." + mp2
// call
var req = &github_com_nats_rpc_nrpc.Void{}
var resp = SimpleStringReply{}
if err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {
return nil, err
}
return &resp, nil
}
func (c *SvcSubjectParamsClient) MtStreamedReplyWithSubjectParams(
ctx context.Context,mp1 string,mp2 string,
cb func (context.Context, *SimpleStringReply),
) error {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + c.SvcParamclientid + "." + "mtstreamedreplywithsubjectparams" + "." + mp1 + "." + mp2
sub, err := nrpc.StreamCall(ctx, c.nc, subject, &nrpc.Void{}, c.Encoding, c.Timeout)
if err != nil {
return err
}
var res SimpleStringReply
for {
err = sub.Next(&res)
if err != nil {
break
}
cb(ctx, &res)
}
if err == nrpc.ErrEOS {
err = nil
}
return err
}
func (c *SvcSubjectParamsClient) MtNoReply() (error) {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + c.SvcParamclientid + "." + "mtnoreply"
// call
var req = &github_com_nats_rpc_nrpc.Void{}
var resp = github_com_nats_rpc_nrpc.NoReply{}
if err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {
return err
}
return nil
}
func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubject(
mtmp1 string,
) string {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + c.SvcParamclientid + "." + "mtnorequestwparams" + "." + mtmp1
if c.Encoding != "protobuf" {
subject += "." + c.Encoding
}
return subject
}
type SvcSubjectParamsMtNoRequestWParamsSubscription struct {
*nats.Subscription
encoding string
}
func (s *SvcSubjectParamsMtNoRequestWParamsSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {
msg, err := s.Subscription.NextMsg(timeout)
if err != nil {
return
}
err = nrpc.Unmarshal(s.encoding, msg.Data, &next)
return
}
func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeSync(
mtmp1 string,
) (sub *SvcSubjectParamsMtNoRequestWParamsSubscription, err error) {
subject := c.MtNoRequestWParamsSubject(
mtmp1,
)
natsSub, err := c.nc.SubscribeSync(subject)
if err != nil {
return
}
sub = &SvcSubjectParamsMtNoRequestWParamsSubscription{natsSub, c.Encoding}
return
}
func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribe(
mtmp1 string,
handler func (*SimpleStringReply),
) (sub *nats.Subscription, err error) {
subject := c.MtNoRequestWParamsSubject(
mtmp1,
)
sub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){
var pmsg SimpleStringReply
err := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)
if err != nil {
log.Printf("SvcSubjectParamsClient.MtNoRequestWParamsSubscribe: Error decoding, %s", err)
return
}
handler(&pmsg)
})
return
}
func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeChan(
mtmp1 string,
) (<-chan *SimpleStringReply, *nats.Subscription, error) {
ch := make(chan *SimpleStringReply)
sub, err := c.MtNoRequestWParamsSubscribe(mtmp1, func (msg *SimpleStringReply) {
ch <- msg
})
return ch, sub, err
}
// NoRequestServiceServer is the interface that providers of the service
// NoRequestService should implement.
type NoRequestServiceServer interface {
}
// NoRequestServiceHandler provides a NATS subscription handler that can serve a
// subscription using a given NoRequestServiceServer implementation.
type NoRequestServiceHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server NoRequestServiceServer
encodings []string
}
func NewNoRequestServiceHandler(ctx context.Context, nc nrpc.NatsConn, s NoRequestServiceServer) *NoRequestServiceHandler {
return &NoRequestServiceHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewNoRequestServiceConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s NoRequestServiceServer) *NoRequestServiceHandler {
return &NoRequestServiceHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *NoRequestServiceHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *NoRequestServiceHandler) Subject() string {
return "root.*.norequestservice.>"
}
func (h *NoRequestServiceHandler) MtNoRequestPublish(pkginstance string, msg *SimpleStringReply) error {
for _, encoding := range h.encodings {
rawMsg, err := nrpc.Marshal(encoding, msg)
if err != nil {
log.Printf("NoRequestServiceHandler.MtNoRequestPublish: error marshaling the message: %s", err)
return err
}
subject := "root." + pkginstance + "."+ "norequestservice."+ "mtnorequest"
if encoding != "protobuf" {
subject += "." + encoding
}
if err := h.nc.Publish(subject, rawMsg); err != nil {
return err
}
}
return nil
}
type NoRequestServiceClient struct {
nc nrpc.NatsConn
PkgSubject string
PkgParaminstance string
Subject string
Encoding string
Timeout time.Duration
}
func NewNoRequestServiceClient(nc nrpc.NatsConn, pkgParaminstance string) *NoRequestServiceClient {
return &NoRequestServiceClient{
nc: nc,
PkgSubject: "root",
PkgParaminstance: pkgParaminstance,
Subject: "norequestservice",
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *NoRequestServiceClient) MtNoRequestSubject(
) string {
subject := c.PkgSubject + "." + c.PkgParaminstance + "." + c.Subject + "." + "mtnorequest"
if c.Encoding != "protobuf" {
subject += "." + c.Encoding
}
return subject
}
type NoRequestServiceMtNoRequestSubscription struct {
*nats.Subscription
encoding string
}
func (s *NoRequestServiceMtNoRequestSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {
msg, err := s.Subscription.NextMsg(timeout)
if err != nil {
return
}
err = nrpc.Unmarshal(s.encoding, msg.Data, &next)
return
}
func (c *NoRequestServiceClient) MtNoRequestSubscribeSync(
) (sub *NoRequestServiceMtNoRequestSubscription, err error) {
subject := c.MtNoRequestSubject(
)
natsSub, err := c.nc.SubscribeSync(subject)
if err != nil {
return
}
sub = &NoRequestServiceMtNoRequestSubscription{natsSub, c.Encoding}
return
}
func (c *NoRequestServiceClient) MtNoRequestSubscribe(
handler func (*SimpleStringReply),
) (sub *nats.Subscription, err error) {
subject := c.MtNoRequestSubject(
)
sub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){
var pmsg SimpleStringReply
err := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)
if err != nil {
log.Printf("NoRequestServiceClient.MtNoRequestSubscribe: Error decoding, %s", err)
return
}
handler(&pmsg)
})
return
}
func (c *NoRequestServiceClient) MtNoRequestSubscribeChan(
) (<-chan *SimpleStringReply, *nats.Subscription, error) {
ch := make(chan *SimpleStringReply)
sub, err := c.MtNoRequestSubscribe(func (msg *SimpleStringReply) {
ch <- msg
})
return ch, sub, err
}
type Client struct {
nc nrpc.NatsConn
defaultEncoding string
defaultTimeout time.Duration
pkgSubject string
pkgParaminstance string
SvcCustomSubject *SvcCustomSubjectClient
SvcSubjectParams *SvcSubjectParamsClient
NoRequestService *NoRequestServiceClient
}
func NewClient(nc nrpc.NatsConn, pkgParaminstance string) *Client {
c := Client{
nc: nc,
defaultEncoding: "protobuf",
defaultTimeout: 5*time.Second,
pkgSubject: "root",
pkgParaminstance: pkgParaminstance,
}
c.SvcCustomSubject = NewSvcCustomSubjectClient(nc, c.pkgParaminstance)
c.NoRequestService = NewNoRequestServiceClient(nc, c.pkgParaminstance)
return &c
}
func (c *Client) SetEncoding(encoding string) {
c.defaultEncoding = encoding
if c.SvcCustomSubject != nil {
c.SvcCustomSubject.Encoding = encoding
}
if c.SvcSubjectParams != nil {
c.SvcSubjectParams.Encoding = encoding
}
if c.NoRequestService != nil {
c.NoRequestService.Encoding = encoding
}
}
func (c *Client) SetTimeout(t time.Duration) {
c.defaultTimeout = t
if c.SvcCustomSubject != nil {
c.SvcCustomSubject.Timeout = t
}
if c.SvcSubjectParams != nil {
c.SvcSubjectParams.Timeout = t
}
if c.NoRequestService != nil {
c.NoRequestService.Timeout = t
}
}
func (c *Client) SetSvcSubjectParamsParams(
clientid string,
) {
c.SvcSubjectParams = NewSvcSubjectParamsClient(
c.nc,
c.pkgParaminstance,
clientid,
)
c.SvcSubjectParams.Encoding = c.defaultEncoding
c.SvcSubjectParams.Timeout = c.defaultTimeout
}
func (c *Client) NewSvcSubjectParams(
clientid string,
) *SvcSubjectParamsClient {
client := NewSvcSubjectParamsClient(
c.nc,
c.pkgParaminstance,
clientid,
)
client.Encoding = c.defaultEncoding
client.Timeout = c.defaultTimeout
return client
}
================================================
FILE: examples/alloptions/alloptions.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.0
// protoc v4.22.2
// source: alloptions.proto
package main
import (
nrpc "github.com/nats-rpc/nrpc"
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 StringArg struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Arg1 string `protobuf:"bytes,1,opt,name=arg1,proto3" json:"arg1,omitempty"`
}
func (x *StringArg) Reset() {
*x = StringArg{}
if protoimpl.UnsafeEnabled {
mi := &file_alloptions_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *StringArg) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StringArg) ProtoMessage() {}
func (x *StringArg) ProtoReflect() protoreflect.Message {
mi := &file_alloptions_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 StringArg.ProtoReflect.Descriptor instead.
func (*StringArg) Descriptor() ([]byte, []int) {
return file_alloptions_proto_rawDescGZIP(), []int{0}
}
func (x *StringArg) GetArg1() string {
if x != nil {
return x.Arg1
}
return ""
}
type SimpleStringReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Reply string `protobuf:"bytes,1,opt,name=reply,proto3" json:"reply,omitempty"`
}
func (x *SimpleStringReply) Reset() {
*x = SimpleStringReply{}
if protoimpl.UnsafeEnabled {
mi := &file_alloptions_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SimpleStringReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SimpleStringReply) ProtoMessage() {}
func (x *SimpleStringReply) ProtoReflect() protoreflect.Message {
mi := &file_alloptions_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 SimpleStringReply.ProtoReflect.Descriptor instead.
func (*SimpleStringReply) Descriptor() ([]byte, []int) {
return file_alloptions_proto_rawDescGZIP(), []int{1}
}
func (x *SimpleStringReply) GetReply() string {
if x != nil {
return x.Reply
}
return ""
}
var File_alloptions_proto protoreflect.FileDescriptor
var file_alloptions_proto_rawDesc = []byte{
0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x0f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x6e,
0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, 0x09, 0x53, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x22, 0x29, 0x0a, 0x11, 0x53, 0x69,
0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x72, 0x65, 0x70, 0x6c, 0x79, 0x32, 0xeb, 0x02, 0x0a, 0x10, 0x53, 0x76, 0x63, 0x43, 0x75, 0x73,
0x74, 0x6f, 0x6d, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x4d, 0x74,
0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e, 0x6d, 0x61,
0x69, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x17, 0x2e, 0x6d,
0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x17, 0x82, 0xb2, 0x19, 0x0f, 0x6d, 0x74, 0x5f, 0x73, 0x69,
0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x98, 0xb2, 0x19, 0x01, 0x12, 0x2c,
0x0a, 0x0b, 0x4d, 0x74, 0x56, 0x6f, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e,
0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x0a,
0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0b,
0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x6e, 0x72,
0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d,
0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0f, 0x4d, 0x74, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e, 0x6d, 0x61, 0x69,
0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x17, 0x2e, 0x6d, 0x61,
0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x22, 0x04, 0x90, 0xb2, 0x19, 0x01, 0x12, 0x43, 0x0a, 0x16, 0x4d, 0x74,
0x56, 0x6f, 0x69, 0x64, 0x52, 0x65, 0x71, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x64, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x12, 0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64,
0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x04, 0x90, 0xb2, 0x19, 0x01, 0x1a,
0x12, 0xc2, 0xf3, 0x18, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x75, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x32, 0xbc, 0x02, 0x0a, 0x10, 0x53, 0x76, 0x63, 0x53, 0x75, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4a, 0x0a, 0x13, 0x4d, 0x74, 0x57, 0x69,
0x74, 0x68, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12,
0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x17, 0x2e, 0x6d, 0x61,
0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x22, 0x0e, 0x8a, 0xb2, 0x19, 0x03, 0x6d, 0x70, 0x31, 0x8a, 0xb2, 0x19,
0x03, 0x6d, 0x70, 0x32, 0x12, 0x5b, 0x0a, 0x20, 0x4d, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e,
0x56, 0x6f, 0x69, 0x64, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70,
0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, 0x8a,
0xb2, 0x19, 0x03, 0x6d, 0x70, 0x31, 0x8a, 0xb2, 0x19, 0x03, 0x6d, 0x70, 0x32, 0x90, 0xb2, 0x19,
0x01, 0x12, 0x28, 0x0a, 0x09, 0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0a,
0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x0d, 0x2e, 0x6e, 0x72, 0x70,
0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x12, 0x4d,
0x74, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x73, 0x12, 0x0f, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x07, 0x8a, 0xb2, 0x19,
0x03, 0x6d, 0x70, 0x31, 0x1a, 0x0c, 0xca, 0xf3, 0x18, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x69, 0x64, 0x32, 0x4d, 0x0a, 0x10, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69,
0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
0x00, 0x42, 0x24, 0x82, 0xb5, 0x18, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x8a, 0xb5, 0x18, 0x08, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x90, 0xb5, 0x18, 0x01, 0x98, 0xb5, 0x18, 0x01, 0x5a,
0x06, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_alloptions_proto_rawDescOnce sync.Once
file_alloptions_proto_rawDescData = file_alloptions_proto_rawDesc
)
func file_alloptions_proto_rawDescGZIP() []byte {
file_alloptions_proto_rawDescOnce.Do(func() {
file_alloptions_proto_rawDescData = protoimpl.X.CompressGZIP(file_alloptions_proto_rawDescData)
})
return file_alloptions_proto_rawDescData
}
var file_alloptions_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_alloptions_proto_goTypes = []interface{}{
(*StringArg)(nil), // 0: main.StringArg
(*SimpleStringReply)(nil), // 1: main.SimpleStringReply
(*nrpc.NoRequest)(nil), // 2: nrpc.NoRequest
(*nrpc.Void)(nil), // 3: nrpc.Void
(*nrpc.NoReply)(nil), // 4: nrpc.NoReply
}
var file_alloptions_proto_depIdxs = []int32{
0, // 0: main.SvcCustomSubject.MtSimpleReply:input_type -> main.StringArg
0, // 1: main.SvcCustomSubject.MtVoidReply:input_type -> main.StringArg
2, // 2: main.SvcCustomSubject.MtNoRequest:input_type -> nrpc.NoRequest
0, // 3: main.SvcCustomSubject.MtStreamedReply:input_type -> main.StringArg
3, // 4: main.SvcCustomSubject.MtVoidReqStreamedReply:input_type -> nrpc.Void
3, // 5: main.SvcSubjectParams.MtWithSubjectParams:input_type -> nrpc.Void
3, // 6: main.SvcSubjectParams.MtStreamedReplyWithSubjectParams:input_type -> nrpc.Void
3, // 7: main.SvcSubjectParams.MtNoReply:input_type -> nrpc.Void
2, // 8: main.SvcSubjectParams.MtNoRequestWParams:input_type -> nrpc.NoRequest
2, // 9: main.NoRequestService.MtNoRequest:input_type -> nrpc.NoRequest
1, // 10: main.SvcCustomSubject.MtSimpleReply:output_type -> main.SimpleStringReply
3, // 11: main.SvcCustomSubject.MtVoidReply:output_type -> nrpc.Void
1, // 12: main.SvcCustomSubject.MtNoRequest:output_type -> main.SimpleStringReply
1, // 13: main.SvcCustomSubject.MtStreamedReply:output_type -> main.SimpleStringReply
1, // 14: main.SvcCustomSubject.MtVoidReqStreamedReply:output_type -> main.SimpleStringReply
1, // 15: main.SvcSubjectParams.MtWithSubjectParams:output_type -> main.SimpleStringReply
1, // 16: main.SvcSubjectParams.MtStreamedReplyWithSubjectParams:output_type -> main.SimpleStringReply
4, // 17: main.SvcSubjectParams.MtNoReply:output_type -> nrpc.NoReply
1, // 18: main.SvcSubjectParams.MtNoRequestWParams:output_type -> main.SimpleStringReply
1, // 19: main.NoRequestService.MtNoRequest:output_type -> main.SimpleStringReply
10, // [10:20] is the sub-list for method output_type
0, // [0:10] 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_alloptions_proto_init() }
func file_alloptions_proto_init() {
if File_alloptions_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_alloptions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StringArg); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_alloptions_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SimpleStringReply); 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_alloptions_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 3,
},
GoTypes: file_alloptions_proto_goTypes,
DependencyIndexes: file_alloptions_proto_depIdxs,
MessageInfos: file_alloptions_proto_msgTypes,
}.Build()
File_alloptions_proto = out.File
file_alloptions_proto_rawDesc = nil
file_alloptions_proto_goTypes = nil
file_alloptions_proto_depIdxs = nil
}
================================================
FILE: examples/alloptions/alloptions.proto
================================================
syntax = "proto3";
package main;
option go_package = ".;main";
import "nrpc/nrpc.proto";
option (nrpc.packageSubject) = "root";
option (nrpc.packageSubjectParams) = "instance";
option (nrpc.serviceSubjectRule) = TOLOWER;
option (nrpc.methodSubjectRule) = TOLOWER;
service SvcCustomSubject {
option (nrpc.serviceSubject) = 'custom_subject';
rpc MtSimpleReply(StringArg) returns (SimpleStringReply) {
option (nrpc.methodSubject) = "mt_simple_reply";
option (nrpc.pollingEnabled) = true;
}
rpc MtVoidReply(StringArg) returns (nrpc.Void) {}
rpc MtNoRequest(nrpc.NoRequest) returns (SimpleStringReply) {}
rpc MtStreamedReply(StringArg) returns (SimpleStringReply) {
option (nrpc.streamedReply) = true;
}
rpc MtVoidReqStreamedReply(nrpc.Void) returns (SimpleStringReply) {
option (nrpc.streamedReply) = true;
}
}
service SvcSubjectParams {
option (nrpc.serviceSubjectParams) = "clientid";
rpc MtWithSubjectParams(nrpc.Void) returns (SimpleStringReply) {
option (nrpc.methodSubjectParams) = "mp1";
option (nrpc.methodSubjectParams) = "mp2";
}
rpc MtStreamedReplyWithSubjectParams(nrpc.Void) returns (SimpleStringReply) {
option (nrpc.streamedReply) = true;
option (nrpc.methodSubjectParams) = "mp1";
option (nrpc.methodSubjectParams) = "mp2";
}
rpc MtNoReply(nrpc.Void) returns (nrpc.NoReply) {}
rpc MtNoRequestWParams(nrpc.NoRequest) returns (SimpleStringReply) {
option (nrpc.methodSubjectParams) = "mp1";
}
}
service NoRequestService {
rpc MtNoRequest(nrpc.NoRequest) returns (SimpleStringReply) {}
}
message StringArg {
string arg1 = 1;
}
message SimpleStringReply {
string reply = 1;
}
================================================
FILE: examples/alloptions/alloptions_test.go
================================================
package main
import (
"context"
"errors"
"fmt"
"log"
"sync"
"testing"
"time"
"github.com/nats-io/nats.go"
"github.com/nats-rpc/nrpc"
"github.com/stretchr/testify/require"
)
type TestingLogWriter struct {
t *testing.T
}
func (w TestingLogWriter) Write(p []byte) (int, error) {
w.t.Log(string(p))
return len(p), nil
}
type BasicServerImpl struct {
t *testing.T
handler *SvcCustomSubjectHandler
handler2 *SvcSubjectParamsHandler
}
func (s BasicServerImpl) MtSimpleReply(
ctx context.Context, args *StringArg,
) (*SimpleStringReply, error) {
if instance := nrpc.GetRequest(ctx).PackageParam("instance"); instance != "default" {
s.t.Errorf("Got an invalid package param instance: '%s'", instance)
}
return &SimpleStringReply{Reply: args.Arg1}, nil
}
func (s BasicServerImpl) MtVoidReply(
ctx context.Context, args *StringArg,
) error {
if args.GetArg1() == "please fail" {
return errors.New("Error")
}
return nil
}
func (s BasicServerImpl) MtStreamedReply(
ctx context.Context, req *StringArg, send func(rep *SimpleStringReply),
) error {
if req.GetArg1() == "please fail" {
panic("Failing")
}
if req.GetArg1() == "very long call" {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Minute):
time.Sleep(time.Minute)
return nil
}
}
time.Sleep(time.Second)
send(&SimpleStringReply{Reply: "msg1"})
time.Sleep(250 * time.Millisecond)
send(&SimpleStringReply{Reply: "msg2"})
time.Sleep(250 * time.Millisecond)
send(&SimpleStringReply{Reply: "msg3"})
time.Sleep(250 * time.Millisecond)
return nil
}
func (s BasicServerImpl) MtVoidReqStreamedReply(
ctx context.Context, send func(rep *SimpleStringReply),
) error {
time.Sleep(2 * time.Second)
send(&SimpleStringReply{Reply: "hi"})
return nil
}
func (s BasicServerImpl) MtNoReply(ctx context.Context) {
s.t.Log("Will publish to MtNoRequest")
s.handler.MtNoRequestPublish("default", &SimpleStringReply{Reply: "Hi there"})
s.handler2.MtNoRequestWParamsPublish("default", "me", "mtvalue", &SimpleStringReply{Reply: "Hi there"})
}
func (s BasicServerImpl) MtWithSubjectParams(
ctx context.Context, mp1 string, mp2 string,
) (*SimpleStringReply, error) {
var err error
if mp1 != "p1" {
err = fmt.Errorf("Expects method param mp1 = 'p1', got '%s'", mp1)
}
if mp2 != "p2" {
err = fmt.Errorf("Expects method param mp2 = 'p2', got '%s'", mp2)
}
return &SimpleStringReply{Reply: "Hi"}, err
}
func (s BasicServerImpl) MtStreamedReplyWithSubjectParams(
ctx context.Context, mp1 string, mp2 string, send func(rep *SimpleStringReply),
) error {
send(&SimpleStringReply{Reply: mp1})
send(&SimpleStringReply{Reply: mp2})
return nil
}
func TestAll(t *testing.T) {
c, err := nats.Connect(natsURL)
if err != nil {
t.Fatal(err)
}
log.SetOutput(TestingLogWriter{t})
t.Run("MultiProtocolPublish", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
handler := NewSvcCustomSubjectHandler(context.Background(), c, BasicServerImpl{t, nil, nil})
handler.SetEncodings([]string{"protobuf", "json"})
c1 := NewSvcCustomSubjectClient(c, "default")
for _, protocol := range []string{"protobuf", "json"} {
t.Run(protocol, func(t *testing.T) {
c1.Encoding = protocol
if protocol == "protobuf" {
require.Equal(t, "root.default.custom_subject.mtnorequest", c1.MtNoRequestSubject())
} else {
require.Equal(t, "root.default.custom_subject.mtnorequest."+protocol, c1.MtNoRequestSubject())
}
sub, err := c1.MtNoRequestSubscribeSync()
if err != nil {
t.Fatal(err)
}
defer sub.Unsubscribe()
if err := handler.MtNoRequestPublish(
"default", &SimpleStringReply{Reply: "test"},
); err != nil {
t.Fatal(t)
}
msg, err := sub.Next(time.Second)
if err != nil {
t.Fatal(err)
}
require.Equal(t, "test", msg.GetReply())
})
}
})
t.Run("NoConcurrency", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
handler1 := NewSvcCustomSubjectHandler(context.Background(), c, BasicServerImpl{t, nil, nil})
impl := BasicServerImpl{t, handler1, nil}
handler2 := NewSvcSubjectParamsHandler(context.Background(), c, &impl)
impl.handler2 = handler2
if handler1.Subject() != "root.*.custom_subject.>" {
t.Fatal("Invalid subject", handler1.Subject())
}
if handler2.Subject() != "root.*.svcsubjectparams.*.>" {
t.Fatal("Invalid subject", handler2.Subject())
}
for _, encoding := range []string{"protobuf", "json"} {
t.Run("Encoding_"+encoding, commonTests(c, handler1, handler2, encoding))
}
})
t.Run("WithConcurrency", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
pool := nrpc.NewWorkerPool(context.Background(), 2, 5, 4*time.Second)
handler1 := NewSvcCustomSubjectConcurrentHandler(pool, c, BasicServerImpl{t, nil, nil})
impl := BasicServerImpl{t, handler1, nil}
handler2 := NewSvcSubjectParamsConcurrentHandler(pool, c, &impl)
impl.handler2 = handler2
if handler1.Subject() != "root.*.custom_subject.>" {
t.Fatal("Invalid subject", handler1.Subject())
}
if handler2.Subject() != "root.*.svcsubjectparams.*.>" {
t.Fatal("Invalid subject", handler2.Subject())
}
for _, encoding := range []string{"protobuf", "json"} {
t.Run("Encoding_"+encoding, commonTests(c, handler1, handler2, encoding))
}
// Now a few tests very specific to concurrency handling
s, err := c.QueueSubscribe(handler1.Subject(), "queue", handler1.Handler)
if err != nil {
t.Fatal(err)
}
defer s.Unsubscribe()
s, err = c.QueueSubscribe(handler2.Subject(), "queue", handler2.Handler)
if err != nil {
t.Fatal(err)
}
defer s.Unsubscribe()
c1 := NewSvcCustomSubjectClient(c, "default")
// c2 := NewSvcSubjectParamsClient(c, "default", "me")
t.Run("Concurrent Stream calls", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
var resList []string
var wg sync.WaitGroup
resChan := make(chan string, 2)
go func() {
for r := range resChan {
resList = append(resList, r)
}
}()
for i := 0; i != 2; i++ {
wg.Add(1)
go func() {
defer wg.Done()
err := c1.MtStreamedReply(
context.Background(),
&StringArg{Arg1: "arg"},
func(ctx context.Context, rep *SimpleStringReply) {
fmt.Println("received", rep)
resChan <- rep.GetReply()
})
if err != nil {
t.Error(err)
}
}()
}
wg.Wait()
close(resChan)
expectsStringSlice(t,
[]string{"msg1", "msg1", "msg2", "msg2", "msg3", "msg3"},
resList)
})
t.Run("Too many concurrent Stream calls", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
pool.SetMaxPendingDuration(2 * time.Second)
var resList []string
var wg sync.WaitGroup
resChan := make(chan string, 2)
go func() {
for r := range resChan {
resList = append(resList, r)
}
}()
for i := 0; i != 7; i++ {
wg.Add(1)
time.Sleep(50 * time.Millisecond)
go func(i int) {
defer wg.Done()
err := c1.MtStreamedReply(
context.Background(),
&StringArg{Arg1: "arg"},
func(ctx context.Context, rep *SimpleStringReply) {
fmt.Println("received", rep)
resChan <- rep.GetReply()
})
if i >= 4 {
if nrpcErr, ok := err.(*nrpc.Error); !ok || nrpcErr.Type != nrpc.Error_SERVERTOOBUSY {
t.Errorf("Should get a SERVERTOOBUSY error, got %v", err)
}
} else if err != nil {
t.Errorf("Should succeed but got: %s", err)
}
}(i)
}
// Wait so the 7 calls are already queued
time.Sleep(200 * time.Millisecond)
// The 7th call should get a SERVERTOOBUSY error
err := c1.MtStreamedReply(
context.Background(),
&StringArg{Arg1: "arg"},
func(ctx context.Context, rep *SimpleStringReply) {
fmt.Println("received", rep)
})
if err == nil {
t.Error("Should get an error")
} else if nrpcErr, ok := err.(*nrpc.Error); ok {
if nrpcErr.Type != nrpc.Error_SERVERTOOBUSY {
t.Errorf("Should get a SERVERTOOBUSY, got %v", nrpcErr.Type)
}
} else {
t.Errorf("Should get a nrpcError, got %v", err)
}
wg.Wait()
close(resChan)
})
pool.Close(time.Second)
})
}
func commonTests(
conn *nats.Conn,
handler1 *SvcCustomSubjectHandler,
handler2 *SvcSubjectParamsHandler,
encoding string,
) func(t *testing.T) {
return func(t *testing.T) {
handler1.SetEncodings([]string{encoding})
handler2.SetEncodings([]string{encoding})
s, err := conn.QueueSubscribe(handler1.Subject(), "queue", handler1.Handler)
if err != nil {
t.Fatal(err)
}
defer s.Unsubscribe()
s, err = conn.QueueSubscribe(handler2.Subject(), "queue", handler2.Handler)
if err != nil {
t.Fatal(err)
}
defer s.Unsubscribe()
c1 := NewSvcCustomSubjectClient(conn, "default")
c2 := NewSvcSubjectParamsClient(conn, "default", "me")
c1.Encoding = encoding
c2.Encoding = encoding
r, err := c1.MtSimpleReply(&StringArg{Arg1: "hi"})
if err != nil {
t.Fatal(err)
}
if r.GetReply() != "hi" {
t.Error("Invalid reply:", r.GetReply())
}
if err := c1.MtSimpleReplyPoll(&StringArg{Arg1: "hi"}, 1,
func(r *SimpleStringReply) error {
if r.GetReply() != "hi" {
return fmt.Errorf("Invalid reply: %s", r.GetReply())
}
return nil
},
); err != nil {
t.Fatal(err)
}
if err := c1.MtVoidReply(&StringArg{Arg1: "hi"}); err != nil {
t.Error("Unexpected error:", err)
}
err = c1.MtVoidReply(&StringArg{Arg1: "please fail"})
if err == nil {
t.Error("Expected an error")
}
t.Run("StreamedReply", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
t.Run("Simple", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
var resList []string
err := c1.MtStreamedReply(
context.Background(),
&StringArg{Arg1: "arg"},
func(ctx context.Context, rep *SimpleStringReply) {
fmt.Println("received", rep)
resList = append(resList, rep.GetReply())
})
if err != nil {
t.Fatal(err)
}
if resList[0] != "msg1" {
t.Errorf("Expected 'msg1', got '%s'", resList[0])
}
if resList[1] != "msg2" {
t.Errorf("Expected 'msg2', got '%s'", resList[1])
}
if resList[2] != "msg3" {
t.Errorf("Expected 'msg3', got '%s'", resList[2])
}
})
t.Run("Error", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
err := c1.MtStreamedReply(context.Background(),
&StringArg{Arg1: "please fail"},
func(ctx context.Context, rep *SimpleStringReply) {
t.Fatal("Should not receive anything")
})
if err == nil {
t.Fatal("Expected an error, got nil")
}
})
t.Run("Cancel", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
ctx, cancel := context.WithTimeout(context.Background(), 7*time.Second)
defer cancel()
err := c1.MtStreamedReply(ctx,
&StringArg{Arg1: "very long call"},
func(context.Context, *SimpleStringReply) {
t.Fatal("Should not receive anything")
})
if err != nrpc.ErrCanceled {
t.Fatal("Expects a ErrCanceled error, got ", err)
}
})
t.Run("VoidRequest", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := c1.MtVoidReqStreamedReply(ctx, func(context.Context, *SimpleStringReply) {})
if err != nil {
fmt.Print(err)
t.Error(err)
}
})
})
t.Run("SubjectParams", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
r, err = c2.MtWithSubjectParams("p1", "p2")
if err != nil {
t.Fatal(err)
}
if r.GetReply() != "Hi" {
t.Error("Invalid reply:", r.GetReply())
}
r, err = c2.MtWithSubjectParams("invalid", "p2")
if err == nil {
t.Error("Expected an error")
}
if nErr, ok := err.(*nrpc.Error); ok {
if nErr.Type != nrpc.Error_CLIENT || nErr.Message != "Expects method param mp1 = 'p1', got 'invalid'" {
t.Errorf("Unexpected error %#v", nErr)
}
} else {
t.Errorf("Expected a nrpc.Error, got %#v", err)
}
})
t.Run("StreamedReply with SubjectParams", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
var resList []string
err := c2.MtStreamedReplyWithSubjectParams(
context.Background(),
"arg1", "arg2",
func(ctx context.Context, rep *SimpleStringReply) {
resList = append(resList, rep.GetReply())
})
if err != nil {
t.Fatal(err)
}
if resList[0] != "arg1" {
t.Errorf("Expected 'arg1', got '%s'", resList[0])
}
if resList[1] != "arg2" {
t.Errorf("Expected 'arg2', got '%s'", resList[1])
}
})
t.Run("NoRequest method with params", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
sub, err := c2.MtNoRequestWParamsSubscribeSync(
"mtvalue",
)
if err != nil {
t.Fatal(err)
}
defer sub.Unsubscribe()
c2.MtNoReply()
reply, err := sub.Next(time.Second)
if err != nil {
t.Fatal(err)
}
if reply.GetReply() != "Hi there" {
t.Errorf("Expected 'Hi there', got %s", reply.GetReply())
}
})
t.Run("NoRequest method subscriptions", func(t *testing.T) {
log.SetOutput(TestingLogWriter{t})
if encoding != "protobuf" {
t.Skip()
}
fmt.Println("Subscribing")
sub1, err := c1.MtNoRequestSubscribeSync()
if err != nil {
t.Fatal(err)
}
defer sub1.Unsubscribe()
repChan := make(chan string, 2)
sub2, err := c1.MtNoRequestSubscribe(func(msg *SimpleStringReply) {
repChan <- msg.GetReply()
})
if err != nil {
t.Fatal(err)
}
defer sub2.Unsubscribe()
msgChan, sub3, err := c1.MtNoRequestSubscribeChan()
if err != nil {
t.Fatal(err)
}
defer sub3.Unsubscribe()
go func() {
msg := <-msgChan
repChan <- msg.GetReply()
}()
err = c2.MtNoReply()
if err != nil {
t.Fatal(err)
}
msg, err := sub1.Next(time.Second)
if err != nil {
t.Fatal(err)
}
if msg.GetReply() != "Hi there" {
t.Errorf("Expected 'Hi there', got '%s'", msg.GetReply())
}
for range []int{0, 1} {
select {
case rep := <-repChan:
if rep != "Hi there" {
t.Errorf("Expected 'Hi there', got '%s'", rep)
}
case <-time.After(time.Second):
t.Fatal("timeout")
}
}
})
}
}
func expectsStringSlice(t *testing.T, expected, actual []string) {
if len(expected) != len(actual) {
t.Errorf("Expected %v, got %v", expected, actual)
return
}
for i := range expected {
if expected[i] != actual[i] {
t.Errorf("Expected %v, got %v", expected, actual)
return
}
}
}
================================================
FILE: examples/alloptions/main.go
================================================
package main
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/nats-io/nats.go"
"github.com/nats-rpc/nrpc"
)
//go:generate protoc -I. -I ../../.. --go_out . --nrpc_out . alloptions.proto
type ServerImpl struct {
handler *SvcCustomSubjectHandler
handler2 *SvcSubjectParamsHandler
}
func (s ServerImpl) MtSimpleReply(
ctx context.Context, args *StringArg,
) (*SimpleStringReply, error) {
fmt.Println("MtSimpleReply: " + args.GetArg1())
if instance := nrpc.GetRequest(ctx).PackageParam("instance"); instance != "default" {
return nil, fmt.Errorf("Got an invalid package param instance: '%s'", instance)
}
return &SimpleStringReply{Reply: args.Arg1}, nil
}
func (s ServerImpl) MtVoidReply(
ctx context.Context, args *StringArg,
) error {
fmt.Println("MtVoidReply: " + args.GetArg1())
if args.GetArg1() == "please fail" {
return errors.New("Error")
}
return nil
}
func (s ServerImpl) MtStreamedReply(
ctx context.Context, req *StringArg, send func(rep *SimpleStringReply),
) error {
fmt.Println("MtStreamedReply: " + req.GetArg1())
if req.GetArg1() == "please fail" {
panic("Failing")
}
if req.GetArg1() == "very long call" {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(time.Minute):
time.Sleep(time.Minute)
return nil
}
}
time.Sleep(time.Second)
send(&SimpleStringReply{Reply: "msg1"})
time.Sleep(250 * time.Millisecond)
send(&SimpleStringReply{Reply: "msg2"})
time.Sleep(250 * time.Millisecond)
send(&SimpleStringReply{Reply: "msg3"})
time.Sleep(250 * time.Millisecond)
return nil
}
func (s ServerImpl) MtVoidReqStreamedReply(
ctx context.Context, send func(rep *SimpleStringReply),
) error {
fmt.Println("MtVoidReqStreamedReply")
time.Sleep(2 * time.Second)
send(&SimpleStringReply{Reply: "hi"})
return nil
}
func (s ServerImpl) MtNoReply(ctx context.Context) {
fmt.Println("MtNoReply")
if err := s.handler.MtNoRequestPublish("default", &SimpleStringReply{Reply: "Hi there"}); err != nil {
fmt.Println(err)
}
if err := s.handler2.MtNoRequestWParamsPublish("default", "me", "mtvalue", &SimpleStringReply{Reply: "Hi there"}); err != nil {
fmt.Println(err)
}
}
func (s ServerImpl) MtWithSubjectParams(
ctx context.Context, mp1 string, mp2 string,
) (*SimpleStringReply, error) {
fmt.Println("MtWithSubjectParams: ", mp1, mp2)
var err error
if mp1 != "p1" {
err = fmt.Errorf("Expects method param mp1 = 'p1', got '%s'", mp1)
}
if mp2 != "p2" {
err = fmt.Errorf("Expects method param mp2 = 'p2', got '%s'", mp2)
}
return &SimpleStringReply{Reply: "Hi"}, err
}
func (s ServerImpl) MtStreamedReplyWithSubjectParams(
ctx context.Context, mp1 string, mp2 string, send func(rep *SimpleStringReply),
) error {
fmt.Println("MtStreamedReplyWithSubjectParams: ", mp1, mp2)
send(&SimpleStringReply{Reply: mp1})
send(&SimpleStringReply{Reply: mp2})
return nil
}
func main() {
c, err := nats.Connect("localhost:4222")
if err != nil {
fmt.Println(err)
return
}
pool := nrpc.NewWorkerPool(context.Background(), 2, 5, 4*time.Second)
impl := ServerImpl{nil, nil}
handler1 := NewSvcCustomSubjectConcurrentHandler(pool, c, &impl)
handler2 := NewSvcSubjectParamsConcurrentHandler(pool, c, &impl)
impl.handler = handler1
impl.handler2 = handler2
s, err := c.QueueSubscribe(handler1.Subject(), "queue", handler1.Handler)
if err != nil {
panic(err)
}
defer s.Unsubscribe()
s, err = c.QueueSubscribe(handler2.Subject(), "queue", handler2.Handler)
if err != nil {
panic(err)
}
defer s.Unsubscribe()
done := make(chan os.Signal, 1)
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("Blocking, press ctrl+c to continue...")
<-done // Will block here until user hits ctrl+c
}
================================================
FILE: examples/alloptions/testrunner_test.go
================================================
package main
import (
"log"
"os"
"testing"
"time"
"github.com/nats-io/nats-server/v2/logger"
natsServer "github.com/nats-io/nats-server/v2/server"
)
var natsURL string
func TestMain(m *testing.M) {
gnatsd := natsServer.New(&natsServer.Options{Port: natsServer.RANDOM_PORT})
gnatsd.SetLogger(
logger.NewStdLogger(false, false, false, false, false),
false, false)
go gnatsd.Start()
defer gnatsd.Shutdown()
if !gnatsd.ReadyForConnections(time.Second) {
log.Fatal("Cannot start the gnatsd server")
}
natsURL = "nats://" + gnatsd.Addr().String()
os.Exit(m.Run())
}
================================================
FILE: examples/helloworld/greeter_client/main.go
================================================
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/nats-io/nats.go"
// This is the package containing the generated *.pb.go and *.nrpc.go
// files.
"github.com/nats-rpc/nrpc/examples/helloworld/helloworld"
)
func main() {
var natsURL = nats.DefaultURL
if len(os.Args) == 2 {
natsURL = os.Args[1]
}
// Connect to the NATS server.
nc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// This is our generated client.
cli := helloworld.NewGreeterClient(nc)
// Contact the server and print out its response.
resp, err := cli.SayHello(&helloworld.HelloRequest{Name: "world"})
if err != nil {
log.Fatal(err)
}
// print
fmt.Printf("Greeting: %s\n", resp.GetMessage())
}
================================================
FILE: examples/helloworld/greeter_server/main.go
================================================
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"time"
"github.com/nats-io/nats.go"
// This is the package containing the generated *.pb.go and *.nrpc.go
// files.
"github.com/nats-rpc/nrpc/examples/helloworld/helloworld"
)
// server implements the helloworld.GreeterServer interface.
type server struct{}
// SayHello is an implementation of the SayHello method from the definition of
// the Greeter service.
func (s *server) SayHello(ctx context.Context, req *helloworld.HelloRequest) (resp *helloworld.HelloReply, err error) {
return &helloworld.HelloReply{Message: "Hello " + req.Name}, nil
}
func main() {
var natsURL = nats.DefaultURL
if len(os.Args) == 2 {
natsURL = os.Args[1]
}
// Connect to the NATS server.
nc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// Our server implementation.
s := &server{}
// The NATS handler from the helloworld.nrpc.proto file.
h := helloworld.NewGreeterHandler(context.TODO(), nc, s)
// Start a NATS subscription using the handler. You can also use the
// QueueSubscribe() method for a load-balanced set of servers.
sub, err := nc.Subscribe(h.Subject(), h.Handler)
if err != nil {
log.Fatal(err)
}
defer sub.Unsubscribe()
// Keep running until ^C.
fmt.Println("server is running, ^C quits.")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
close(c)
}
================================================
FILE: examples/helloworld/greeter_server/main_test.go
================================================
package main
import (
"context"
"testing"
"time"
"github.com/nats-io/nats.go"
// This is the package containing the generated *.pb.go and *.nrpc.go
// files.
"github.com/nats-rpc/nrpc/examples/helloworld/helloworld"
)
func TestBasic(t *testing.T) {
// Connect to the NATS server.
nc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))
if err != nil {
t.Fatal(err)
}
defer nc.Close()
// Our server implementation.
s := &server{}
// The NATS handler from the helloworld.nrpc.proto file.
h := helloworld.NewGreeterHandler(context.TODO(), nc, s)
// Start a NATS subscription using the handler. You can also use the
// QueueSubscribe() method for a load-balanced set of servers.
sub, err := nc.Subscribe(h.Subject(), h.Handler)
if err != nil {
t.Fatal(err)
}
defer sub.Unsubscribe()
// This is our generated client.
cli := helloworld.NewGreeterClient(nc)
// Contact the server and print out its response.
resp, err := cli.SayHello(&helloworld.HelloRequest{Name: "world"})
if err != nil {
t.Fatal(err)
}
if resp.GetMessage() != "Hello world" {
t.Fatalf("unexpected message: %s", resp.GetMessage())
}
}
================================================
FILE: examples/helloworld/greeter_server/testrunner_test.go
================================================
package main
import (
"log"
"os"
"testing"
"time"
"github.com/nats-io/nats-server/v2/logger"
natsServer "github.com/nats-io/nats-server/v2/server"
)
var natsURL string
func TestMain(m *testing.M) {
gnatsd := natsServer.New(&natsServer.Options{Port: natsServer.RANDOM_PORT})
gnatsd.SetLogger(
logger.NewStdLogger(false, false, false, false, false),
false, false)
go gnatsd.Start()
defer gnatsd.Shutdown()
if !gnatsd.ReadyForConnections(time.Second) {
log.Fatal("Cannot start the gnatsd server")
}
natsURL = "nats://" + gnatsd.Addr().String()
os.Exit(m.Run())
}
================================================
FILE: examples/helloworld/helloworld/helloworld.go
================================================
package helloworld
//go:generate protoc -I. -I../../.. --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_opt=paths=source_relative helloworld.proto
================================================
FILE: examples/helloworld/helloworld/helloworld.nrpc.go
================================================
// This code was autogenerated from helloworld.proto, do not edit.
package helloworld
import (
"context"
"log"
"time"
"google.golang.org/protobuf/proto"
"github.com/nats-io/nats.go"
"github.com/nats-rpc/nrpc"
)
// GreeterServer is the interface that providers of the service
// Greeter should implement.
type GreeterServer interface {
SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error)
}
// GreeterHandler provides a NATS subscription handler that can serve a
// subscription using a given GreeterServer implementation.
type GreeterHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server GreeterServer
encodings []string
}
func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *GreeterHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *GreeterHandler) Subject() string {
return "Greeter.>"
}
func (h *GreeterHandler) Handler(msg *nats.Msg) {
var ctx context.Context
if h.workers != nil {
ctx = h.workers.Context
} else {
ctx = h.ctx
}
request := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)
// extract method name & encoding from subject
_, _, name, tail, err := nrpc.ParseSubject(
"", 0, "Greeter", 0, msg.Subject)
if err != nil {
log.Printf("GreeterHanlder: Greeter subject parsing failed: %v", err)
return
}
request.MethodName = name
request.SubjectTail = tail
// call handler and form response
var immediateError *nrpc.Error
switch name {
case "SayHello":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("SayHelloHanlder: SayHello subject parsing failed: %v", err)
break
}
var req HelloRequest
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("SayHelloHandler: SayHello request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
innerResp, err := h.server.SayHello(ctx, &req)
if err != nil {
return nil, err
}
return innerResp, err
}
}
default:
log.Printf("GreeterHandler: unknown name %q", name)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "unknown name: " + name,
}
}
if immediateError == nil {
if h.workers != nil {
// Try queuing the request
if err := h.workers.QueueRequest(request); err != nil {
log.Printf("nrpc: Error queuing the request: %s", err)
}
} else {
// Run the handler synchronously
request.RunAndReply()
}
}
if immediateError != nil {
if err := request.SendReply(nil, immediateError); err != nil {
log.Printf("GreeterHandler: Greeter handler failed to publish the response: %s", err)
}
} else {
}
}
type GreeterClient struct {
nc nrpc.NatsConn
Subject string
Encoding string
Timeout time.Duration
}
func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
return &GreeterClient{
nc: nc,
Subject: "Greeter",
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *GreeterClient) SayHello(req *HelloRequest) (*HelloReply, error) {
subject := c.Subject + "." + "SayHello"
// call
var resp = HelloReply{}
if err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {
return nil, err
}
return &resp, nil
}
type Client struct {
nc nrpc.NatsConn
defaultEncoding string
defaultTimeout time.Duration
Greeter *GreeterClient
}
func NewClient(nc nrpc.NatsConn) *Client {
c := Client{
nc: nc,
defaultEncoding: "protobuf",
defaultTimeout: 5*time.Second,
}
c.Greeter = NewGreeterClient(nc)
return &c
}
func (c *Client) SetEncoding(encoding string) {
c.defaultEncoding = encoding
if c.Greeter != nil {
c.Greeter.Encoding = encoding
}
}
func (c *Client) SetTimeout(t time.Duration) {
c.defaultTimeout = t
if c.Greeter != nil {
c.Greeter.Timeout = t
}
}
================================================
FILE: examples/helloworld/helloworld/helloworld.pb.go
================================================
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.0
// protoc v4.22.2
// source: helloworld.proto
package helloworld
import (
_ "github.com/nats-rpc/nrpc"
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)
)
// The request message containing the user's name.
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *HelloReply) Reset() {
*x = HelloReply{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloReply) ProtoMessage() {}
func (x *HelloReply) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{1}
}
func (x *HelloReply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_helloworld_proto protoreflect.FileDescriptor
var file_helloworld_proto_rawDesc = []byte{
0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x0a,
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26,
0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x49, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65,
0x72, 0x12, 0x3e, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x2e,
0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,
0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
0x00, 0x42, 0x69, 0x0a, 0x1b, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x42, 0x0f, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c,
0x64, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_helloworld_proto_rawDescOnce sync.Once
file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc
)
func file_helloworld_proto_rawDescGZIP() []byte {
file_helloworld_proto_rawDescOnce.Do(func() {
file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)
})
return file_helloworld_proto_rawDescData
}
var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_helloworld_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: helloworld.HelloRequest
(*HelloReply)(nil), // 1: helloworld.HelloReply
}
var file_helloworld_proto_depIdxs = []int32{
0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
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_helloworld_proto_init() }
func file_helloworld_proto_init() {
if File_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloReply); 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_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_helloworld_proto_goTypes,
DependencyIndexes: file_helloworld_proto_depIdxs,
MessageInfos: file_helloworld_proto_msgTypes,
}.Build()
File_helloworld_proto = out.File
file_helloworld_proto_rawDesc = nil
file_helloworld_proto_goTypes = nil
file_helloworld_proto_depIdxs = nil
}
================================================
FILE: examples/helloworld/helloworld/helloworld.proto
================================================
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
import "nrpc.proto";
package helloworld;
option go_package = "github.com/nats-rpc/nrpc/examples/helloworld/helloworld";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
================================================
FILE: examples/metrics_helloworld/helloworld/helloworld.go
================================================
package helloworld
//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out plugins=prometheus:. --nrpc_opt=paths=source_relative helloworld.proto
================================================
FILE: examples/metrics_helloworld/helloworld/helloworld.nrpc.go
================================================
// This code was autogenerated from helloworld.proto, do not edit.
package helloworld
import (
"context"
"log"
"time"
"google.golang.org/protobuf/proto"
"github.com/nats-io/nats.go"
"github.com/prometheus/client_golang/prometheus"
"github.com/nats-rpc/nrpc"
)
// GreeterServer is the interface that providers of the service
// Greeter should implement.
type GreeterServer interface {
SayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)
}
var (
// The request completion time, measured at client-side.
clientRCTForGreeter = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "nrpc_client_request_completion_time_seconds",
Help: "The request completion time for calls, measured client-side.",
Objectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},
ConstLabels: map[string]string{
"service": "Greeter",
},
},
[]string{"method"})
// The handler execution time, measured at server-side.
serverHETForGreeter = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "nrpc_server_handler_execution_time_seconds",
Help: "The handler execution time for calls, measured server-side.",
Objectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},
ConstLabels: map[string]string{
"service": "Greeter",
},
},
[]string{"method"})
// The counts of calls made by the client, classified by result type.
clientCallsForGreeter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "nrpc_client_calls_count",
Help: "The count of calls made by the client.",
ConstLabels: map[string]string{
"service": "Greeter",
},
},
[]string{"method", "encoding", "result_type"})
// The counts of requests handled by the server, classified by result type.
serverRequestsForGreeter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "nrpc_server_requests_count",
Help: "The count of requests handled by the server.",
ConstLabels: map[string]string{
"service": "Greeter",
},
},
[]string{"method", "encoding", "result_type"})
)
// GreeterHandler provides a NATS subscription handler that can serve a
// subscription using a given GreeterServer implementation.
type GreeterHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server GreeterServer
encodings []string
}
func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *GreeterHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *GreeterHandler) Subject() string {
return "Greeter.>"
}
func (h *GreeterHandler) Handler(msg *nats.Msg) {
var ctx context.Context
if h.workers != nil {
ctx = h.workers.Context
} else {
ctx = h.ctx
}
request := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)
// extract method name & encoding from subject
_, _, name, tail, err := nrpc.ParseSubject(
"", 0, "Greeter", 0, msg.Subject)
if err != nil {
log.Printf("GreeterHanlder: Greeter subject parsing failed: %v", err)
return
}
request.MethodName = name
request.SubjectTail = tail
// call handler and form response
var immediateError *nrpc.Error
switch name {
case "SayHello":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("SayHelloHanlder: SayHello subject parsing failed: %v", err)
break
}
var req HelloRequest
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("SayHelloHandler: SayHello request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
serverRequestsForGreeter.WithLabelValues(
"SayHello", request.Encoding, "unmarshal_fail").Inc()
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
innerResp, err := h.server.SayHello(ctx, req)
if err != nil {
return nil, err
}
return &innerResp, err
}
}
default:
log.Printf("GreeterHandler: unknown name %q", name)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "unknown name: " + name,
}
serverRequestsForGreeter.WithLabelValues(
"Greeter", request.Encoding, "name_fail").Inc()
}
request.AfterReply = func(request *nrpc.Request, success, replySuccess bool) {
if !replySuccess {
serverRequestsForGreeter.WithLabelValues(
request.MethodName, request.Encoding, "sendreply_fail").Inc()
}
if success {
serverRequestsForGreeter.WithLabelValues(
request.MethodName, request.Encoding, "success").Inc()
} else {
serverRequestsForGreeter.WithLabelValues(
request.MethodName, request.Encoding, "handler_fail").Inc()
}
// report metric to Prometheus
serverHETForGreeter.WithLabelValues(request.MethodName).Observe(
request.Elapsed().Seconds())
}
if immediateError == nil {
if h.workers != nil {
// Try queuing the request
if err := h.workers.QueueRequest(request); err != nil {
log.Printf("nrpc: Error queuing the request: %s", err)
}
} else {
// Run the handler synchronously
request.RunAndReply()
}
}
if immediateError != nil {
if err := request.SendReply(nil, immediateError); err != nil {
log.Printf("GreeterHandler: Greeter handler failed to publish the response: %s", err)
serverRequestsForGreeter.WithLabelValues(
request.MethodName, request.Encoding, "handler_fail").Inc()
}
serverHETForGreeter.WithLabelValues(request.MethodName).Observe(
request.Elapsed().Seconds())
} else {
}
}
type GreeterClient struct {
nc nrpc.NatsConn
Subject string
Encoding string
Timeout time.Duration
}
func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
return &GreeterClient{
nc: nc,
Subject: "Greeter",
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {
start := time.Now()
subject := c.Subject + "." + "SayHello"
// call
err = nrpc.Call(&req, &resp, c.nc, subject, c.Encoding, c.Timeout)
if err != nil {
clientCallsForGreeter.WithLabelValues(
"SayHello", c.Encoding, "call_fail").Inc()
return // already logged
}
// report total time taken to Prometheus
elapsed := time.Since(start).Seconds()
clientRCTForGreeter.WithLabelValues("SayHello").Observe(elapsed)
clientCallsForGreeter.WithLabelValues(
"SayHello", c.Encoding, "success").Inc()
return
}
type Client struct {
nc nrpc.NatsConn
defaultEncoding string
defaultTimeout time.Duration
Greeter *GreeterClient
}
func NewClient(nc nrpc.NatsConn) *Client {
c := Client{
nc: nc,
defaultEncoding: "protobuf",
defaultTimeout: 5*time.Second,
}
c.Greeter = NewGreeterClient(nc)
return &c
}
func (c *Client) SetEncoding(encoding string) {
c.defaultEncoding = encoding
if c.Greeter != nil {
c.Greeter.Encoding = encoding
}
}
func (c *Client) SetTimeout(t time.Duration) {
c.defaultTimeout = t
if c.Greeter != nil {
c.Greeter.Timeout = t
}
}
func init() {
// register metrics for service Greeter
prometheus.MustRegister(clientRCTForGreeter)
prometheus.MustRegister(serverHETForGreeter)
prometheus.MustRegister(clientCallsForGreeter)
prometheus.MustRegister(serverRequestsForGreeter)
}
================================================
FILE: examples/metrics_helloworld/helloworld/helloworld.pb.go
================================================
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.0
// protoc v4.22.2
// source: helloworld.proto
package helloworld
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)
)
// The request message containing the user's name.
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *HelloReply) Reset() {
*x = HelloReply{}
if protoimpl.UnsafeEnabled {
mi := &file_helloworld_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloReply) ProtoMessage() {}
func (x *HelloReply) ProtoReflect() protoreflect.Message {
mi := &file_helloworld_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 HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
return file_helloworld_proto_rawDescGZIP(), []int{1}
}
func (x *HelloReply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_helloworld_proto protoreflect.FileDescriptor
var file_helloworld_proto_rawDesc = []byte{
0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x22,
0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x49, 0x0a, 0x07, 0x47, 0x72,
0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c,
0x6f, 0x12, 0x18, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65,
0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65,
0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x71, 0x0a, 0x1b, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63,
0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,
0x6f, 0x72, 0x6c, 0x64, 0x42, 0x0f, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64,
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70,
0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x73, 0x5f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65,
0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_helloworld_proto_rawDescOnce sync.Once
file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc
)
func file_helloworld_proto_rawDescGZIP() []byte {
file_helloworld_proto_rawDescOnce.Do(func() {
file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)
})
return file_helloworld_proto_rawDescData
}
var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_helloworld_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: helloworld.HelloRequest
(*HelloReply)(nil), // 1: helloworld.HelloReply
}
var file_helloworld_proto_depIdxs = []int32{
0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
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_helloworld_proto_init() }
func file_helloworld_proto_init() {
if File_helloworld_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloReply); 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_helloworld_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_helloworld_proto_goTypes,
DependencyIndexes: file_helloworld_proto_depIdxs,
MessageInfos: file_helloworld_proto_msgTypes,
}.Build()
File_helloworld_proto = out.File
file_helloworld_proto_rawDesc = nil
file_helloworld_proto_goTypes = nil
file_helloworld_proto_depIdxs = nil
}
================================================
FILE: examples/metrics_helloworld/helloworld/helloworld.proto
================================================
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
package helloworld;
option go_package = "github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
================================================
FILE: examples/metrics_helloworld/metrics_greeter_client/main.go
================================================
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/nats-io/nats.go"
// This is the package containing the generated *.pb.go and *.nrpc.go
// files.
"github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld"
// If you've used the prometheus plugin when generating the code, you
// can import the HTTP handler of Prometheus to serve up the metrics.
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
// Connect to the NATS server.
nc, err := nats.Connect(nats.DefaultURL, nats.Timeout(5*time.Second))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// This is our generated client.
cli := helloworld.NewGreeterClient(nc)
// Contact the server and print out its response.
resp, err := cli.SayHello(helloworld.HelloRequest{Name: "world"})
if err != nil {
log.Fatal(err)
}
// print
fmt.Printf("Greeting: %s\n", resp.Message)
// Do this block only if you generated the code with the prometheus plugin.
fmt.Println("Check metrics at http://localhost:6061/metrics. Hit ^C to exit.")
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":6061", nil)
}
================================================
FILE: examples/metrics_helloworld/metrics_greeter_server/main.go
================================================
package main
import (
"context"
"errors"
"fmt"
"log"
"math/rand"
"net/http"
"os"
"os/signal"
"time"
"github.com/nats-io/nats.go"
// This is the package containing the generated *.pb.go and *.nrpc.go
// files.
"github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld"
// If you've used the prometheus plugin when generating the code, you
// can import the HTTP handler of Prometheus to serve up the metrics.
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// server implements the helloworld.GreeterServer interface.
type server struct{}
// SayHello is an implementation of the SayHello method from the definition of
// the Greeter service.
func (s *server) SayHello(ctx context.Context, req helloworld.HelloRequest) (resp helloworld.HelloReply, err error) {
resp.Message = "Hello " + req.Name
if rand.Intn(10) < 7 { // will fail 70% of the time
err = errors.New("random failure simulated")
}
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) // random delay
return
}
func main() {
// Connect to the NATS server.
nc, err := nats.Connect(nats.DefaultURL, nats.Timeout(5*time.Second))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// Our server implementation.
s := &server{}
rand.Seed(time.Now().UnixNano())
// The NATS handler from the helloworld.nrpc.proto file.
h := helloworld.NewGreeterHandler(context.TODO(), nc, s)
// Start a NATS subscription using the handler. You can also use the
// QueueSubscribe() method for a load-balanced set of servers.
sub, err := nc.Subscribe(h.Subject(), h.Handler)
if err != nil {
log.Fatal(err)
}
defer sub.Unsubscribe()
// Do this block only if you generated the code with the prometheus plugin.
http.Handle("/metrics", promhttp.Handler())
go http.ListenAndServe(":6060", nil)
// Keep running until ^C.
fmt.Println("server is running, ^C quits.")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
close(c)
}
================================================
FILE: examples/nooption/nooption.go
================================================
package nooption
//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_opt=paths=source_relative nooption.proto
================================================
FILE: examples/nooption/nooption.nrpc.go
================================================
// This code was autogenerated from nooption.proto, do not edit.
package nooption
import (
"context"
"log"
"time"
"google.golang.org/protobuf/proto"
"github.com/nats-io/nats.go"
"github.com/nats-rpc/nrpc"
)
// GreeterServer is the interface that providers of the service
// Greeter should implement.
type GreeterServer interface {
SayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)
}
// GreeterHandler provides a NATS subscription handler that can serve a
// subscription using a given GreeterServer implementation.
type GreeterHandler struct {
ctx context.Context
workers *nrpc.WorkerPool
nc nrpc.NatsConn
server GreeterServer
encodings []string
}
func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
ctx: ctx,
nc: nc,
server: s,
encodings: []string{"protobuf"},
}
}
func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {
return &GreeterHandler{
workers: workers,
nc: nc,
server: s,
}
}
// SetEncodings sets the output encodings when using a '*Publish' function
func (h *GreeterHandler) SetEncodings(encodings []string) {
h.encodings = encodings
}
func (h *GreeterHandler) Subject() string {
return "Greeter.>"
}
func (h *GreeterHandler) Handler(msg *nats.Msg) {
var ctx context.Context
if h.workers != nil {
ctx = h.workers.Context
} else {
ctx = h.ctx
}
request := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)
// extract method name & encoding from subject
_, _, name, tail, err := nrpc.ParseSubject(
"", 0, "Greeter", 0, msg.Subject)
if err != nil {
log.Printf("GreeterHanlder: Greeter subject parsing failed: %v", err)
return
}
request.MethodName = name
request.SubjectTail = tail
// call handler and form response
var immediateError *nrpc.Error
switch name {
case "SayHello":
_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)
if err != nil {
log.Printf("SayHelloHanlder: SayHello subject parsing failed: %v", err)
break
}
var req HelloRequest
if err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {
log.Printf("SayHelloHandler: SayHello request unmarshal failed: %v", err)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "bad request received: " + err.Error(),
}
} else {
request.Handler = func(ctx context.Context)(proto.Message, error){
innerResp, err := h.server.SayHello(ctx, req)
if err != nil {
return nil, err
}
return &innerResp, err
}
}
default:
log.Printf("GreeterHandler: unknown name %q", name)
immediateError = &nrpc.Error{
Type: nrpc.Error_CLIENT,
Message: "unknown name: " + name,
}
}
if immediateError == nil {
if h.workers != nil {
// Try queuing the request
if err := h.workers.QueueRequest(request); err != nil {
log.Printf("nrpc: Error queuing the request: %s", err)
}
} else {
// Run the handler synchronously
request.RunAndReply()
}
}
if immediateError != nil {
if err := request.SendReply(nil, immediateError); err != nil {
log.Printf("GreeterHandler: Greeter handler failed to publish the response: %s", err)
}
} else {
}
}
type GreeterClient struct {
nc nrpc.NatsConn
Subject string
Encoding string
Timeout time.Duration
}
func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
return &GreeterClient{
nc: nc,
Subject: "Greeter",
Encoding: "protobuf",
Timeout: 5 * time.Second,
}
}
func (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {
subject := c.Subject + "." + "SayHello"
// call
err = nrpc.Call(&req, &resp, c.nc, subject, c.Encoding, c.Timeout)
if err != nil {
return // already logged
}
return
}
type Client struct {
nc nrpc.NatsConn
defaultEncoding string
defaultTimeout time.Duration
Greeter *GreeterClient
}
func NewClient(nc nrpc.NatsConn) *Client {
c := Client{
nc: nc,
defaultEncoding: "protobuf",
defaultTimeout: 5*time.Second,
}
c.Greeter = NewGreeterClient(nc)
return &c
}
func (c *Client) SetEncoding(encoding string) {
c.defaultEncoding = encoding
if c.Greeter != nil {
c.Greeter.Encoding = encoding
}
}
func (c *Client) SetTimeout(t time.Duration) {
c.defaultTimeout = t
if c.Greeter != nil {
c.Greeter.Timeout = t
}
}
================================================
FILE: examples/nooption/nooption.pb.go
================================================
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.0
// protoc v4.22.2
// source: nooption.proto
package nooption
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)
)
// The request message containing the user's name.
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_nooption_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_nooption_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 HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_nooption_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *HelloReply) Reset() {
*x = HelloReply{}
if protoimpl.UnsafeEnabled {
mi := &file_nooption_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloReply) ProtoMessage() {}
func (x *HelloReply) ProtoReflect() protoreflect.Message {
mi := &file_nooption_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 HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
return file_nooption_proto_rawDescGZIP(), []int{1}
}
func (x *HelloReply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_nooption_proto protoreflect.FileDescriptor
var file_nooption_proto_rawDesc = []byte{
0x0a, 0x0e, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x08, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26,
0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x45, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65,
0x72, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x16, 0x2e,
0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x2c, 0x5a,
0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73,
0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
0x65, 0x73, 0x2f, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
file_nooption_proto_rawDescOnce sync.Once
file_nooption_proto_rawDescData = file_nooption_proto_rawDesc
)
func file_nooption_proto_rawDescGZIP() []byte {
file_nooption_proto_rawDescOnce.Do(func() {
file_nooption_proto_rawDescData = protoimpl.X.CompressGZIP(file_nooption_proto_rawDescData)
})
return file_nooption_proto_rawDescData
}
var file_nooption_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_nooption_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: nooption.HelloRequest
(*HelloReply)(nil), // 1: nooption.HelloReply
}
var file_nooption_proto_depIdxs = []int32{
0, // 0: nooption.Greeter.SayHello:input_type -> nooption.HelloRequest
1, // 1: nooption.Greeter.SayHello:output_type -> nooption.HelloReply
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_nooption_proto_init() }
func file_nooption_proto_init() {
if File_nooption_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_nooption_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_nooption_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloReply); 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_nooption_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_nooption_proto_goTypes,
DependencyIndexes: file_nooption_proto_depIdxs,
MessageInfos: file_nooption_proto_msgTypes,
}.Build()
File_nooption_proto = out.File
file_nooption_proto_rawDesc = nil
file_nooption_proto_goTypes = nil
file_nooption_proto_depIdxs = nil
}
================================================
FILE: examples/nooption/nooption.proto
================================================
syntax = "proto3";
package nooption;
option go_package = "github.com/nats-rpc/nrpc/examples/nooption";
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
================================================
FILE: go.mod
================================================
module github.com/nats-rpc/nrpc
go 1.11
require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/nats-io/nats-server/v2 v2.9.23
github.com/nats-io/nats.go v1.28.0
github.com/prometheus/client_golang v1.14.0
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/stretchr/testify v1.8.1
google.golang.org/protobuf v1.33.0
)
================================================
FILE: go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak=
github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
github.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU=
github.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0=
github.com/nats-io/nats.go v1.28.0 h1:Th4G6zdsz2d0OqXdfzKLClo6bOfoI/b1kInhRtFIy5c=
github.com/nats-io/nats.go v1.28.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc=
github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=
github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
================================================
FILE: helloworld_test.go
================================================
package nrpc
import (
"bytes"
"os"
"os/exec"
"testing"
"time"
)
func TestHelloWorldExample(t *testing.T) {
// make sure protoc-gen-nrpc is up to date
installGenRPC := exec.Command("go", "install", "./protoc-gen-nrpc")
if out, err := installGenRPC.CombinedOutput(); err != nil {
t.Fatal("Install protoc-gen-nrpc failed", err, ":\n", string(out))
}
// generate the sources
generate := exec.Command("go", "generate", "./examples/helloworld/helloworld")
if out, err := generate.CombinedOutput(); err != nil {
t.Fatal("Generate failed", err, ":\n", string(out))
}
// build
buildServer := exec.Command("go", "build",
"-o", "./examples/helloworld/greeter_server/greeter_server",
"./examples/helloworld/greeter_server")
if out, err := buildServer.CombinedOutput(); err != nil {
t.Fatal("Buid server failed", err, string(out))
}
buildClient := exec.Command("go", "build",
"-o", "./examples/helloworld/greeter_client/greeter_client",
"./examples/helloworld/greeter_client")
if out, err := buildClient.CombinedOutput(); err != nil {
t.Fatal("Buid client failed", err, string(out))
}
// run the server
server := exec.Command("./examples/helloworld/greeter_server/greeter_server", NatsURL)
var serverStdout bytes.Buffer
server.Stdout = &serverStdout
server.Start()
defer func() {
if server.Process != nil {
server.Process.Signal(os.Interrupt)
}
if err := server.Wait(); err != nil {
t.Error("Server run failed:", err)
t.Error("Server output:", serverStdout.String())
}
}()
// Give the server a little time to be ready to handle requests
time.Sleep(250 * time.Millisecond)
// run the client and check its output
client := exec.Command("./examples/helloworld/greeter_client/greeter_client", NatsURL)
timeout := time.AfterFunc(time.Second, func() { client.Process.Kill() })
out, err := client.CombinedOutput()
timeout.Stop()
if err != nil {
t.Fatal("Run client failed with:", err, ", output was:\n", string(out))
}
expectedOuput := "Greeting: Hello world\n"
if string(out) != expectedOuput {
t.Errorf("Wrong client output. Expected '%s', got '%s'",
expectedOuput, string(out))
}
}
================================================
FILE: nrpc.go
================================================
package nrpc
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"log"
"runtime/debug"
"strings"
"sync"
"time"
"github.com/nats-io/nats.go"
jsonpb "google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
const (
statusHeader = "Status"
noResponderStatus = "503"
)
// ContextKey type for storing values into context.Context
type ContextKey int
// ErrStreamInvalidMsgCount is when a stream reply gets a wrong number of messages
var ErrStreamInvalidMsgCount = errors.New("Stream reply received an incorrect number of messages")
//go:generate protoc --go_out=. --go_opt=paths=source_relative nrpc.proto
type NatsConn interface {
Publish(subj string, data []byte) error
PublishRequest(subj, reply string, data []byte) error
Request(subj string, data []byte, timeout time.Duration) (*nats.Msg, error)
ChanSubscribe(subj string, ch chan *nats.Msg) (*nats.Subscription, error)
Subscribe(subj string, handler nats.MsgHandler) (*nats.Subscription, error)
SubscribeSync(subj string) (*nats.Subscription, error)
}
// ReplyInboxMaker returns a new inbox subject for a given nats connection.
type ReplyInboxMaker func(NatsConn) string
// GetReplyInbox is used by StreamCall to get a inbox subject
// It can be changed by a client lib that needs custom inbox subjects
var GetReplyInbox ReplyInboxMaker = func(NatsConn) string {
return nats.NewInbox()
}
func (e *Error) Error() string {
return fmt.Sprintf("%s error: %s", Error_Type_name[int32(e.Type)], e.Message)
}
func Unmarshal(encoding string, data []byte, msg proto.Message) error {
switch encoding {
case "protobuf":
return proto.Unmarshal(data, msg)
case "json":
return jsonpb.Unmarshal(data, msg)
default:
return errors.New("Invalid encoding: " + encoding)
}
}
func UnmarshalResponse(encoding string, data []byte, msg proto.Message) error {
switch encoding {
case "protobuf":
if len(data) > 0 && data[0] == 0 {
var repErr Error
if err := proto.Unmarshal(data[1:], &repErr); err != nil {
return err
}
return &repErr
}
return proto.Unmarshal(data, msg)
case "json":
if len(data) > 13 && bytes.Equal(data[:13], []byte("{\"__error__\":")) {
var rep map[string]json.RawMessage
if err := json.Unmarshal(data, &rep); err != nil {
return err
}
errbuf, ok := rep["__error__"]
if !ok {
panic("invalid error message")
}
var nrpcErr Error
if err := jsonpb.Unmarshal(errbuf, &nrpcErr); err != nil {
return err
}
return &nrpcErr
}
return jsonpb.Unmarshal(data, msg)
default:
return errors.New("Invalid encoding: " + encoding)
}
}
func Marshal(encoding string, msg proto.Message) ([]byte, error) {
switch encoding {
case "protobuf":
return proto.Marshal(msg)
case "json":
return jsonpb.Marshal(msg)
default:
return nil, errors.New("Invalid encoding: " + encoding)
}
}
func MarshalErrorResponse(encoding string, repErr *Error) ([]byte, error) {
switch encoding {
case "protobuf":
b, err := proto.Marshal(repErr)
if err != nil {
return nil, err
}
return append([]byte{0}, b...), nil
case "json":
b, err := jsonpb.Marshal(repErr)
if err != nil {
return nil, err
}
return json.Marshal(map[string]json.RawMessage{
"__error__": json.RawMessage(b),
})
default:
return nil, errors.New("Invalid encoding: " + encoding)
}
}
func ParseSubject(
packageSubject string, packageParamsCount int,
serviceSubject string, serviceParamsCount int,
subject string,
) (packageParams []string, serviceParams []string,
name string, tail []string, err error,
) {
packageSubjectDepth := 0
if packageSubject != "" {
packageSubjectDepth = strings.Count(packageSubject, ".") + 1
}
serviceSubjectDepth := strings.Count(serviceSubject, ".") + 1
subjectMinSize := packageSubjectDepth + packageParamsCount + serviceSubjectDepth + serviceParamsCount + 1
tokens := strings.Split(subject, ".")
if len(tokens) < subjectMinSize {
err = fmt.Errorf(
"Invalid subject len. Expects number of parts >= %d, got %d",
subjectMinSize, len(tokens))
return
}
if packageSubject != "" {
for i, packageSubjectPart := range strings.Split(packageSubject, ".") {
if tokens[i] != packageSubjectPart {
err = fmt.Errorf(
"Invalid subject prefix. Expected '%s', got '%s'",
packageSubjectPart, tokens[i])
return
}
}
tokens = tokens[packageSubjectDepth:]
}
packageParams = tokens[0:packageParamsCount]
tokens = tokens[packageParamsCount:]
for i, serviceSubjectPart := range strings.Split(serviceSubject, ".") {
if tokens[i] != serviceSubjectPart {
err = fmt.Errorf(
"Invalid subject. Service should be '%s', got '%s'",
serviceSubjectPart, tokens[i])
return
}
}
tokens = tokens[serviceSubjectDepth:]
serviceParams = tokens[0:serviceParamsCount]
tokens = tokens[serviceParamsCount:]
name = tokens[0]
tokens = tokens[1:]
tail = tokens
return
}
func ParseSubjectTail(
methodParamsCount int,
tail []string,
) (
methodParams []string, encoding string, err error,
) {
if len(tail) < methodParamsCount || len(tail) > methodParamsCount+1 {
err = fmt.Errorf(
"Invalid subject tail length. Expects %d or %d parts, got %d",
methodParamsCount, methodParamsCount+1, len(tail),
)
return
}
methodParams = tail[:methodParamsCount]
tail = tail[methodParamsCount:]
switch len(tail) {
case 0:
encoding = "protobuf"
case 1:
encoding = tail[0]
default:
panic("Got extra tokens, which should be impossible at this point")
}
return
}
func Call(req proto.Message, rep proto.Message, nc NatsConn, subject string, encoding string, timeout time.Duration) error {
// encode request
rawRequest, err := Marshal(encoding, req)
if err != nil {
log.Printf("nrpc: inner request marshal failed: %v", err)
return err
}
if encoding != "protobuf" {
subject += "." + encoding
}
// call
if _, noreply := rep.(*NoReply); noreply {
err := nc.Publish(subject, rawRequest)
if err != nil {
log.Printf("nrpc: nats publish failed: %v", err)
}
return err
}
msg, err := nc.Request(subject, rawRequest, timeout)
if err != nil {
log.Printf("nrpc: nats request failed: %v", err)
return err
}
data := msg.Data
if err := UnmarshalResponse(encoding, data, rep); err != nil {
if _, isError := err.(*Error); !isError {
log.Printf("nrpc: response unmarshal failed: %v", err)
}
return err
}
return nil
}
func Poll(
req proto.Message, rep proto.Message,
nc NatsConn, subject string, encoding string, timeout time.Duration,
maxreplies int, cb func() error,
) error {
// encode request
rawRequest, err := Marshal(encoding, req)
if err != nil {
log.Printf("nrpc: inner request marshal failed: %v", err)
return err
}
if encoding != "protobuf" {
subject += "." + encoding
}
reply := GetReplyInbox(nc)
replyC := make(chan *nats.Msg)
defer close(replyC)
sub, err := nc.ChanSubscribe(reply, replyC)
defer func() {
if err := sub.Unsubscribe(); err != nil {
log.Printf("nrpc: nats unsubscribe failed: %v", err)
}
}()
if err := nc.PublishRequest(subject, reply, rawRequest); err != nil {
log.Printf("nrpc: nats request failed: %v", err)
return err
}
timeoutC := time.After(timeout)
var replyCount int
for {
select {
case msg := <-replyC:
replyCount++
data := msg.Data
if err := UnmarshalResponse(encoding, data, rep); err != nil {
if _, isError := err.(*Error); !isError {
log.Printf("nrpc: response unmarshal failed: %v", err)
}
return err
}
if err := cb(); err != nil {
return err
}
if replyCount == maxreplies {
return nil
}
case <-timeoutC:
return nats.ErrTimeout
}
}
}
const (
// RequestContextKey is the key for string the request into the context
RequestContextKey ContextKey = iota
)
// NewRequest creates a Request instance
func NewRequest(ctx context.Context, conn NatsConn, subject string, replySubject string) *Request {
return &Request{
Context: ctx,
Conn: conn,
Subject: subject,
ReplySubject: replySubject,
CreatedAt: time.Now(),
}
}
// GetRequest returns the Request associated with a context, or nil if absent
func GetRequest(ctx context.Context) *Request {
request, _ := ctx.Value(RequestContextKey).
gitextract_mwgdltlr/ ├── .gitignore ├── .travis.yml ├── AUTHORS ├── LICENSE ├── README.md ├── alloptions_test.go ├── examples/ │ ├── alloptions/ │ │ ├── alloptions.nrpc.go │ │ ├── alloptions.pb.go │ │ ├── alloptions.proto │ │ ├── alloptions_test.go │ │ ├── main.go │ │ └── testrunner_test.go │ ├── helloworld/ │ │ ├── greeter_client/ │ │ │ └── main.go │ │ ├── greeter_server/ │ │ │ ├── main.go │ │ │ ├── main_test.go │ │ │ └── testrunner_test.go │ │ └── helloworld/ │ │ ├── helloworld.go │ │ ├── helloworld.nrpc.go │ │ ├── helloworld.pb.go │ │ └── helloworld.proto │ ├── metrics_helloworld/ │ │ ├── helloworld/ │ │ │ ├── helloworld.go │ │ │ ├── helloworld.nrpc.go │ │ │ ├── helloworld.pb.go │ │ │ └── helloworld.proto │ │ ├── metrics_greeter_client/ │ │ │ └── main.go │ │ └── metrics_greeter_server/ │ │ └── main.go │ └── nooption/ │ ├── nooption.go │ ├── nooption.nrpc.go │ ├── nooption.pb.go │ └── nooption.proto ├── go.mod ├── go.sum ├── helloworld_test.go ├── nrpc.go ├── nrpc.pb.go ├── nrpc.proto ├── nrpc_test.go ├── nrpc_test.proto ├── nrpcpb_test.go ├── protoc-gen-nrpc/ │ ├── main.go │ └── tmpl.go └── testrunner_test.go
SYMBOL INDEX (369 symbols across 26 files)
FILE: alloptions_test.go
function TestAllOptionsExample (line 11) | func TestAllOptionsExample(t *testing.T) {
FILE: examples/alloptions/alloptions.nrpc.go
type SvcCustomSubjectServer (line 17) | type SvcCustomSubjectServer interface
type SvcCustomSubjectHandler (line 26) | type SvcCustomSubjectHandler struct
method SetEncodings (line 54) | func (h *SvcCustomSubjectHandler) SetEncodings(encodings []string) {
method Subject (line 58) | func (h *SvcCustomSubjectHandler) Subject() string {
method MtNoRequestPublish (line 62) | func (h *SvcCustomSubjectHandler) MtNoRequestPublish(pkginstance strin...
method Handler (line 80) | func (h *SvcCustomSubjectHandler) Handler(msg *nats.Msg) {
function NewSvcCustomSubjectHandler (line 35) | func NewSvcCustomSubjectHandler(ctx context.Context, nc nrpc.NatsConn, s...
function NewSvcCustomSubjectConcurrentHandler (line 45) | func NewSvcCustomSubjectConcurrentHandler(workers *nrpc.WorkerPool, nc n...
type SvcCustomSubjectClient (line 222) | type SvcCustomSubjectClient struct
method MtSimpleReply (line 242) | func (c *SvcCustomSubjectClient) MtSimpleReply(req *StringArg) (*Simpl...
method MtSimpleReplyPoll (line 255) | func (c *SvcCustomSubjectClient) MtSimpleReplyPoll(req *StringArg,maxr...
method MtVoidReply (line 274) | func (c *SvcCustomSubjectClient) MtVoidReply(req *StringArg) (error) {
method MtNoRequestSubject (line 287) | func (c *SvcCustomSubjectClient) MtNoRequestSubject(
method MtNoRequestSubscribeSync (line 312) | func (c *SvcCustomSubjectClient) MtNoRequestSubscribeSync(
method MtNoRequestSubscribe (line 326) | func (c *SvcCustomSubjectClient) MtNoRequestSubscribe(
method MtNoRequestSubscribeChan (line 345) | func (c *SvcCustomSubjectClient) MtNoRequestSubscribeChan(
method MtStreamedReply (line 355) | func (c *SvcCustomSubjectClient) MtStreamedReply(
method MtVoidReqStreamedReply (line 381) | func (c *SvcCustomSubjectClient) MtVoidReqStreamedReply(
function NewSvcCustomSubjectClient (line 231) | func NewSvcCustomSubjectClient(nc nrpc.NatsConn, pkgParaminstance string...
type SvcCustomSubjectMtNoRequestSubscription (line 297) | type SvcCustomSubjectMtNoRequestSubscription struct
method Next (line 303) | func (s *SvcCustomSubjectMtNoRequestSubscription) Next(timeout time.Du...
type SvcSubjectParamsServer (line 408) | type SvcSubjectParamsServer interface
type SvcSubjectParamsHandler (line 416) | type SvcSubjectParamsHandler struct
method SetEncodings (line 444) | func (h *SvcSubjectParamsHandler) SetEncodings(encodings []string) {
method Subject (line 448) | func (h *SvcSubjectParamsHandler) Subject() string {
method MtNoRequestWParamsPublish (line 452) | func (h *SvcSubjectParamsHandler) MtNoRequestWParamsPublish(pkginstanc...
method Handler (line 470) | func (h *SvcSubjectParamsHandler) Handler(msg *nats.Msg) {
function NewSvcSubjectParamsHandler (line 425) | func NewSvcSubjectParamsHandler(ctx context.Context, nc nrpc.NatsConn, s...
function NewSvcSubjectParamsConcurrentHandler (line 435) | func NewSvcSubjectParamsConcurrentHandler(workers *nrpc.WorkerPool, nc n...
type SvcSubjectParamsClient (line 593) | type SvcSubjectParamsClient struct
method MtWithSubjectParams (line 615) | func (c *SvcSubjectParamsClient) MtWithSubjectParams(mp1 string, mp2 s...
method MtStreamedReplyWithSubjectParams (line 629) | func (c *SvcSubjectParamsClient) MtStreamedReplyWithSubjectParams(
method MtNoReply (line 654) | func (c *SvcSubjectParamsClient) MtNoReply() (error) {
method MtNoRequestWParamsSubject (line 668) | func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubject(
method MtNoRequestWParamsSubscribeSync (line 693) | func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeSync(
method MtNoRequestWParamsSubscribe (line 707) | func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribe(
method MtNoRequestWParamsSubscribeChan (line 726) | func (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeChan(
function NewSvcSubjectParamsClient (line 603) | func NewSvcSubjectParamsClient(nc nrpc.NatsConn, pkgParaminstance string...
type SvcSubjectParamsMtNoRequestWParamsSubscription (line 678) | type SvcSubjectParamsMtNoRequestWParamsSubscription struct
method Next (line 684) | func (s *SvcSubjectParamsMtNoRequestWParamsSubscription) Next(timeout ...
type NoRequestServiceServer (line 738) | type NoRequestServiceServer interface
type NoRequestServiceHandler (line 743) | type NoRequestServiceHandler struct
method SetEncodings (line 771) | func (h *NoRequestServiceHandler) SetEncodings(encodings []string) {
method Subject (line 775) | func (h *NoRequestServiceHandler) Subject() string {
method MtNoRequestPublish (line 779) | func (h *NoRequestServiceHandler) MtNoRequestPublish(pkginstance strin...
function NewNoRequestServiceHandler (line 752) | func NewNoRequestServiceHandler(ctx context.Context, nc nrpc.NatsConn, s...
function NewNoRequestServiceConcurrentHandler (line 762) | func NewNoRequestServiceConcurrentHandler(workers *nrpc.WorkerPool, nc n...
type NoRequestServiceClient (line 797) | type NoRequestServiceClient struct
method MtNoRequestSubject (line 817) | func (c *NoRequestServiceClient) MtNoRequestSubject(
method MtNoRequestSubscribeSync (line 842) | func (c *NoRequestServiceClient) MtNoRequestSubscribeSync(
method MtNoRequestSubscribe (line 856) | func (c *NoRequestServiceClient) MtNoRequestSubscribe(
method MtNoRequestSubscribeChan (line 875) | func (c *NoRequestServiceClient) MtNoRequestSubscribeChan(
function NewNoRequestServiceClient (line 806) | func NewNoRequestServiceClient(nc nrpc.NatsConn, pkgParaminstance string...
type NoRequestServiceMtNoRequestSubscription (line 827) | type NoRequestServiceMtNoRequestSubscription struct
method Next (line 833) | func (s *NoRequestServiceMtNoRequestSubscription) Next(timeout time.Du...
type Client (line 885) | type Client struct
method SetEncoding (line 909) | func (c *Client) SetEncoding(encoding string) {
method SetTimeout (line 922) | func (c *Client) SetTimeout(t time.Duration) {
method SetSvcSubjectParamsParams (line 935) | func (c *Client) SetSvcSubjectParamsParams(
method NewSvcSubjectParams (line 947) | func (c *Client) NewSvcSubjectParams(
function NewClient (line 896) | func NewClient(nc nrpc.NatsConn, pkgParaminstance string) *Client {
FILE: examples/alloptions/alloptions.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type StringArg (line 24) | type StringArg struct
method Reset (line 32) | func (x *StringArg) Reset() {
method String (line 41) | func (x *StringArg) String() string {
method ProtoMessage (line 45) | func (*StringArg) ProtoMessage() {}
method ProtoReflect (line 47) | func (x *StringArg) ProtoReflect() protoreflect.Message {
method Descriptor (line 60) | func (*StringArg) Descriptor() ([]byte, []int) {
method GetArg1 (line 64) | func (x *StringArg) GetArg1() string {
type SimpleStringReply (line 71) | type SimpleStringReply struct
method Reset (line 79) | func (x *SimpleStringReply) Reset() {
method String (line 88) | func (x *SimpleStringReply) String() string {
method ProtoMessage (line 92) | func (*SimpleStringReply) ProtoMessage() {}
method ProtoReflect (line 94) | func (x *SimpleStringReply) ProtoReflect() protoreflect.Message {
method Descriptor (line 107) | func (*SimpleStringReply) Descriptor() ([]byte, []int) {
method GetReply (line 111) | func (x *SimpleStringReply) GetReply() string {
function file_alloptions_proto_rawDescGZIP (line 186) | func file_alloptions_proto_rawDescGZIP() []byte {
function init (line 229) | func init() { file_alloptions_proto_init() }
function file_alloptions_proto_init (line 230) | func file_alloptions_proto_init() {
FILE: examples/alloptions/alloptions_test.go
type TestingLogWriter (line 17) | type TestingLogWriter struct
method Write (line 21) | func (w TestingLogWriter) Write(p []byte) (int, error) {
type BasicServerImpl (line 26) | type BasicServerImpl struct
method MtSimpleReply (line 32) | func (s BasicServerImpl) MtSimpleReply(
method MtVoidReply (line 41) | func (s BasicServerImpl) MtVoidReply(
method MtStreamedReply (line 50) | func (s BasicServerImpl) MtStreamedReply(
method MtVoidReqStreamedReply (line 75) | func (s BasicServerImpl) MtVoidReqStreamedReply(
method MtNoReply (line 83) | func (s BasicServerImpl) MtNoReply(ctx context.Context) {
method MtWithSubjectParams (line 89) | func (s BasicServerImpl) MtWithSubjectParams(
method MtStreamedReplyWithSubjectParams (line 102) | func (s BasicServerImpl) MtStreamedReplyWithSubjectParams(
function TestAll (line 110) | func TestAll(t *testing.T) {
function commonTests (line 304) | func commonTests(
function expectsStringSlice (line 537) | func expectsStringSlice(t *testing.T, expected, actual []string) {
FILE: examples/alloptions/main.go
type ServerImpl (line 18) | type ServerImpl struct
method MtSimpleReply (line 23) | func (s ServerImpl) MtSimpleReply(
method MtVoidReply (line 33) | func (s ServerImpl) MtVoidReply(
method MtStreamedReply (line 43) | func (s ServerImpl) MtStreamedReply(
method MtVoidReqStreamedReply (line 69) | func (s ServerImpl) MtVoidReqStreamedReply(
method MtNoReply (line 78) | func (s ServerImpl) MtNoReply(ctx context.Context) {
method MtWithSubjectParams (line 88) | func (s ServerImpl) MtWithSubjectParams(
method MtStreamedReplyWithSubjectParams (line 102) | func (s ServerImpl) MtStreamedReplyWithSubjectParams(
function main (line 111) | func main() {
FILE: examples/alloptions/testrunner_test.go
function TestMain (line 15) | func TestMain(m *testing.M) {
FILE: examples/helloworld/greeter_client/main.go
function main (line 16) | func main() {
FILE: examples/helloworld/greeter_server/main.go
type server (line 19) | type server struct
method SayHello (line 23) | func (s *server) SayHello(ctx context.Context, req *helloworld.HelloRe...
function main (line 27) | func main() {
FILE: examples/helloworld/greeter_server/main_test.go
function TestBasic (line 15) | func TestBasic(t *testing.T) {
FILE: examples/helloworld/greeter_server/testrunner_test.go
function TestMain (line 15) | func TestMain(m *testing.M) {
FILE: examples/helloworld/helloworld/helloworld.nrpc.go
type GreeterServer (line 16) | type GreeterServer interface
type GreeterHandler (line 22) | type GreeterHandler struct
method SetEncodings (line 50) | func (h *GreeterHandler) SetEncodings(encodings []string) {
method Subject (line 54) | func (h *GreeterHandler) Subject() string {
method Handler (line 58) | func (h *GreeterHandler) Handler(msg *nats.Msg) {
function NewGreeterHandler (line 31) | func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterS...
function NewGreeterConcurrentHandler (line 41) | func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsC...
type GreeterClient (line 129) | type GreeterClient struct
method SayHello (line 145) | func (c *GreeterClient) SayHello(req *HelloRequest) (*HelloReply, erro...
function NewGreeterClient (line 136) | func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
type Client (line 158) | type Client struct
method SetEncoding (line 175) | func (c *Client) SetEncoding(encoding string) {
method SetTimeout (line 182) | func (c *Client) SetTimeout(t time.Duration) {
function NewClient (line 165) | func NewClient(nc nrpc.NatsConn) *Client {
FILE: examples/helloworld/helloworld/helloworld.pb.go
constant _ (line 33) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 35) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type HelloRequest (line 39) | type HelloRequest struct
method Reset (line 47) | func (x *HelloRequest) Reset() {
method String (line 56) | func (x *HelloRequest) String() string {
method ProtoMessage (line 60) | func (*HelloRequest) ProtoMessage() {}
method ProtoReflect (line 62) | func (x *HelloRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 75) | func (*HelloRequest) Descriptor() ([]byte, []int) {
method GetName (line 79) | func (x *HelloRequest) GetName() string {
type HelloReply (line 87) | type HelloReply struct
method Reset (line 95) | func (x *HelloReply) Reset() {
method String (line 104) | func (x *HelloReply) String() string {
method ProtoMessage (line 108) | func (*HelloReply) ProtoMessage() {}
method ProtoReflect (line 110) | func (x *HelloReply) ProtoReflect() protoreflect.Message {
method Descriptor (line 123) | func (*HelloReply) Descriptor() ([]byte, []int) {
method GetMessage (line 127) | func (x *HelloReply) GetMessage() string {
function file_helloworld_proto_rawDescGZIP (line 164) | func file_helloworld_proto_rawDescGZIP() []byte {
function init (line 186) | func init() { file_helloworld_proto_init() }
function file_helloworld_proto_init (line 187) | func file_helloworld_proto_init() {
FILE: examples/metrics_helloworld/helloworld/helloworld.nrpc.go
type GreeterServer (line 17) | type GreeterServer interface
type GreeterHandler (line 71) | type GreeterHandler struct
method SetEncodings (line 99) | func (h *GreeterHandler) SetEncodings(encodings []string) {
method Subject (line 103) | func (h *GreeterHandler) Subject() string {
method Handler (line 107) | func (h *GreeterHandler) Handler(msg *nats.Msg) {
function NewGreeterHandler (line 80) | func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterS...
function NewGreeterConcurrentHandler (line 90) | func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsC...
type GreeterClient (line 202) | type GreeterClient struct
method SayHello (line 218) | func (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, e...
function NewGreeterClient (line 209) | func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
type Client (line 240) | type Client struct
method SetEncoding (line 257) | func (c *Client) SetEncoding(encoding string) {
method SetTimeout (line 264) | func (c *Client) SetTimeout(t time.Duration) {
function NewClient (line 247) | func NewClient(nc nrpc.NatsConn) *Client {
function init (line 271) | func init() {
FILE: examples/metrics_helloworld/helloworld/helloworld.pb.go
constant _ (line 32) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 34) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type HelloRequest (line 38) | type HelloRequest struct
method Reset (line 46) | func (x *HelloRequest) Reset() {
method String (line 55) | func (x *HelloRequest) String() string {
method ProtoMessage (line 59) | func (*HelloRequest) ProtoMessage() {}
method ProtoReflect (line 61) | func (x *HelloRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 74) | func (*HelloRequest) Descriptor() ([]byte, []int) {
method GetName (line 78) | func (x *HelloRequest) GetName() string {
type HelloReply (line 86) | type HelloReply struct
method Reset (line 94) | func (x *HelloReply) Reset() {
method String (line 103) | func (x *HelloReply) String() string {
method ProtoMessage (line 107) | func (*HelloReply) ProtoMessage() {}
method ProtoReflect (line 109) | func (x *HelloReply) ProtoReflect() protoreflect.Message {
method Descriptor (line 122) | func (*HelloReply) Descriptor() ([]byte, []int) {
method GetMessage (line 126) | func (x *HelloReply) GetMessage() string {
function file_helloworld_proto_rawDescGZIP (line 162) | func file_helloworld_proto_rawDescGZIP() []byte {
function init (line 184) | func init() { file_helloworld_proto_init() }
function file_helloworld_proto_init (line 185) | func file_helloworld_proto_init() {
FILE: examples/metrics_helloworld/metrics_greeter_client/main.go
function main (line 20) | func main() {
FILE: examples/metrics_helloworld/metrics_greeter_server/main.go
type server (line 26) | type server struct
method SayHello (line 30) | func (s *server) SayHello(ctx context.Context, req helloworld.HelloReq...
function main (line 39) | func main() {
FILE: examples/nooption/nooption.nrpc.go
type GreeterServer (line 16) | type GreeterServer interface
type GreeterHandler (line 22) | type GreeterHandler struct
method SetEncodings (line 50) | func (h *GreeterHandler) SetEncodings(encodings []string) {
method Subject (line 54) | func (h *GreeterHandler) Subject() string {
method Handler (line 58) | func (h *GreeterHandler) Handler(msg *nats.Msg) {
function NewGreeterHandler (line 31) | func NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterS...
function NewGreeterConcurrentHandler (line 41) | func NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsC...
type GreeterClient (line 129) | type GreeterClient struct
method SayHello (line 145) | func (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, e...
function NewGreeterClient (line 136) | func NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {
type Client (line 158) | type Client struct
method SetEncoding (line 175) | func (c *Client) SetEncoding(encoding string) {
method SetTimeout (line 182) | func (c *Client) SetTimeout(t time.Duration) {
function NewClient (line 165) | func NewClient(nc nrpc.NatsConn) *Client {
FILE: examples/nooption/nooption.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type HelloRequest (line 24) | type HelloRequest struct
method Reset (line 32) | func (x *HelloRequest) Reset() {
method String (line 41) | func (x *HelloRequest) String() string {
method ProtoMessage (line 45) | func (*HelloRequest) ProtoMessage() {}
method ProtoReflect (line 47) | func (x *HelloRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 60) | func (*HelloRequest) Descriptor() ([]byte, []int) {
method GetName (line 64) | func (x *HelloRequest) GetName() string {
type HelloReply (line 72) | type HelloReply struct
method Reset (line 80) | func (x *HelloReply) Reset() {
method String (line 89) | func (x *HelloReply) String() string {
method ProtoMessage (line 93) | func (*HelloReply) ProtoMessage() {}
method ProtoReflect (line 95) | func (x *HelloReply) ProtoReflect() protoreflect.Message {
method Descriptor (line 108) | func (*HelloReply) Descriptor() ([]byte, []int) {
method GetMessage (line 112) | func (x *HelloReply) GetMessage() string {
function file_nooption_proto_rawDescGZIP (line 144) | func file_nooption_proto_rawDescGZIP() []byte {
function init (line 166) | func init() { file_nooption_proto_init() }
function file_nooption_proto_init (line 167) | func file_nooption_proto_init() {
FILE: helloworld_test.go
function TestHelloWorldExample (line 11) | func TestHelloWorldExample(t *testing.T) {
FILE: nrpc.go
constant statusHeader (line 21) | statusHeader = "Status"
constant noResponderStatus (line 22) | noResponderStatus = "503"
type ContextKey (line 26) | type ContextKey
type NatsConn (line 33) | type NatsConn interface
type ReplyInboxMaker (line 44) | type ReplyInboxMaker
method Error (line 52) | func (e *Error) Error() string {
function Unmarshal (line 56) | func Unmarshal(encoding string, data []byte, msg proto.Message) error {
function UnmarshalResponse (line 67) | func UnmarshalResponse(encoding string, data []byte, msg proto.Message) ...
function Marshal (line 100) | func Marshal(encoding string, msg proto.Message) ([]byte, error) {
function MarshalErrorResponse (line 111) | func MarshalErrorResponse(encoding string, repErr *Error) ([]byte, error) {
function ParseSubject (line 132) | func ParseSubject(
function ParseSubjectTail (line 188) | func ParseSubjectTail(
function Call (line 214) | func Call(req proto.Message, rep proto.Message, nc NatsConn, subject str...
function Poll (line 252) | func Poll(
constant RequestContextKey (line 314) | RequestContextKey ContextKey = iota
function NewRequest (line 318) | func NewRequest(ctx context.Context, conn NatsConn, subject string, repl...
function GetRequest (line 329) | func GetRequest(ctx context.Context) *Request {
type Request (line 335) | type Request struct
method Elapsed (line 366) | func (r *Request) Elapsed() time.Duration {
method Run (line 372) | func (r *Request) Run() (msg proto.Message, replyError *Error) {
method RunAndReply (line 387) | func (r *Request) RunAndReply() {
method PackageParam (line 409) | func (r *Request) PackageParam(key string) string {
method ServiceParam (line 417) | func (r *Request) ServiceParam(key string) string {
method SetPackageParam (line 425) | func (r *Request) SetPackageParam(key, value string) {
method SetServiceParam (line 433) | func (r *Request) SetServiceParam(key, value string) {
method EnableStreamedReply (line 441) | func (r *Request) EnableStreamedReply() {
method setupStreamedReply (line 446) | func (r *Request) setupStreamedReply() {
method StreamedReply (line 459) | func (r *Request) StreamedReply() bool {
method SendStreamReply (line 464) | func (r *Request) SendStreamReply(msg proto.Message) {
method SendReply (line 474) | func (r *Request) SendReply(resp proto.Message, withError *Error) error {
method sendReply (line 487) | func (r *Request) sendReply(resp proto.Message, withError *Error) error {
method SendErrorTooBusy (line 492) | func (r *Request) SendErrorTooBusy(msg string) error {
function NewStreamCallSubscription (line 502) | func NewStreamCallSubscription(
type StreamCallSubscription (line 527) | type StreamCallSubscription struct
method stop (line 542) | func (sub *StreamCallSubscription) stop() {
method loop (line 546) | func (sub *StreamCallSubscription) loop(ssub *nats.Subscription) {
method Next (line 602) | func (sub *StreamCallSubscription) Next(rep proto.Message) error {
function StreamCall (line 637) | func StreamCall(ctx context.Context, nc NatsConn, subject string, req pr...
function Publish (line 662) | func Publish(resp proto.Message, withError *Error, nc NatsConn, subject ...
function CaptureErrors (line 687) | func CaptureErrors(fn func() (proto.Message, error)) (msg proto.Message,...
function NewKeepStreamAlive (line 711) | func NewKeepStreamAlive(nc NatsConn, subject string, encoding string, on...
type KeepStreamAlive (line 723) | type KeepStreamAlive struct
method Stop (line 731) | func (k *KeepStreamAlive) Stop() {
method loop (line 735) | func (k *KeepStreamAlive) loop() {
type WorkerPool (line 788) | type WorkerPool struct
method getQueue (line 824) | func (pool *WorkerPool) getQueue() (queue chan *Request) {
method scheduler (line 831) | func (pool *WorkerPool) scheduler() {
method worker (line 863) | func (pool *WorkerPool) worker() {
method SetMaxPending (line 874) | func (pool *WorkerPool) SetMaxPending(value uint) {
method SetMaxPendingDuration (line 898) | func (pool *WorkerPool) SetMaxPendingDuration(value time.Duration) {
method SetSize (line 905) | func (pool *WorkerPool) SetSize(size uint) {
method QueueRequest (line 925) | func (pool *WorkerPool) QueueRequest(request *Request) error {
method Close (line 938) | func (pool *WorkerPool) Close(timeout time.Duration) {
function NewWorkerPool (line 803) | func NewWorkerPool(
FILE: nrpc.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type SubjectRule (line 24) | type SubjectRule
method Enum (line 43) | func (x SubjectRule) Enum() *SubjectRule {
method String (line 49) | func (x SubjectRule) String() string {
method Descriptor (line 53) | func (SubjectRule) Descriptor() protoreflect.EnumDescriptor {
method Type (line 57) | func (SubjectRule) Type() protoreflect.EnumType {
method Number (line 61) | func (x SubjectRule) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 66) | func (SubjectRule) EnumDescriptor() ([]byte, []int) {
constant SubjectRule_COPY (line 27) | SubjectRule_COPY SubjectRule = 0
constant SubjectRule_TOLOWER (line 28) | SubjectRule_TOLOWER SubjectRule = 1
type Error_Type (line 70) | type Error_Type
method Enum (line 95) | func (x Error_Type) Enum() *Error_Type {
method String (line 101) | func (x Error_Type) String() string {
method Descriptor (line 105) | func (Error_Type) Descriptor() protoreflect.EnumDescriptor {
method Type (line 109) | func (Error_Type) Type() protoreflect.EnumType {
method Number (line 113) | func (x Error_Type) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 118) | func (Error_Type) EnumDescriptor() ([]byte, []int) {
constant Error_CLIENT (line 73) | Error_CLIENT Error_Type = 0
constant Error_SERVER (line 74) | Error_SERVER Error_Type = 1
constant Error_EOS (line 75) | Error_EOS Error_Type = 3
constant Error_SERVERTOOBUSY (line 76) | Error_SERVERTOOBUSY Error_Type = 4
type Error (line 122) | type Error struct
method Reset (line 132) | func (x *Error) Reset() {
method String (line 141) | func (x *Error) String() string {
method ProtoMessage (line 145) | func (*Error) ProtoMessage() {}
method ProtoReflect (line 147) | func (x *Error) ProtoReflect() protoreflect.Message {
method Descriptor (line 160) | func (*Error) Descriptor() ([]byte, []int) {
method GetType (line 164) | func (x *Error) GetType() Error_Type {
method GetMessage (line 171) | func (x *Error) GetMessage() string {
method GetMsgCount (line 178) | func (x *Error) GetMsgCount() uint32 {
type Void (line 185) | type Void struct
method Reset (line 191) | func (x *Void) Reset() {
method String (line 200) | func (x *Void) String() string {
method ProtoMessage (line 204) | func (*Void) ProtoMessage() {}
method ProtoReflect (line 206) | func (x *Void) ProtoReflect() protoreflect.Message {
method Descriptor (line 219) | func (*Void) Descriptor() ([]byte, []int) {
type NoRequest (line 223) | type NoRequest struct
method Reset (line 229) | func (x *NoRequest) Reset() {
method String (line 238) | func (x *NoRequest) String() string {
method ProtoMessage (line 242) | func (*NoRequest) ProtoMessage() {}
method ProtoReflect (line 244) | func (x *NoRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 257) | func (*NoRequest) Descriptor() ([]byte, []int) {
type NoReply (line 261) | type NoReply struct
method Reset (line 267) | func (x *NoReply) Reset() {
method String (line 276) | func (x *NoReply) String() string {
method ProtoMessage (line 280) | func (*NoReply) ProtoMessage() {}
method ProtoReflect (line 282) | func (x *NoReply) ProtoReflect() protoreflect.Message {
method Descriptor (line 295) | func (*NoReply) Descriptor() ([]byte, []int) {
type HeartBeat (line 299) | type HeartBeat struct
method Reset (line 307) | func (x *HeartBeat) Reset() {
method String (line 316) | func (x *HeartBeat) String() string {
method ProtoMessage (line 320) | func (*HeartBeat) ProtoMessage() {}
method ProtoReflect (line 322) | func (x *HeartBeat) ProtoReflect() protoreflect.Message {
method Descriptor (line 335) | func (*HeartBeat) Descriptor() ([]byte, []int) {
method GetLastbeat (line 339) | func (x *HeartBeat) GetLastbeat() bool {
function file_nrpc_proto_rawDescGZIP (line 565) | func file_nrpc_proto_rawDescGZIP() []byte {
function init (line 607) | func init() { file_nrpc_proto_init() }
function file_nrpc_proto_init (line 608) | func file_nrpc_proto_init() {
FILE: nrpc_test.go
function TestBasic (line 21) | func TestBasic(t *testing.T) {
function TestDecode (line 49) | func TestDecode(t *testing.T) {
function TestStreamCall (line 90) | func TestStreamCall(t *testing.T) {
function TestError (line 209) | func TestError(t *testing.T) {
function TestTimeout (line 239) | func TestTimeout(t *testing.T) {
function TestMarshal (line 276) | func TestMarshal(t *testing.T) {
function TestUnmarshal (line 290) | func TestUnmarshal(t *testing.T) {
function TestMarshalUnmarshalResponse (line 307) | func TestMarshalUnmarshalResponse(t *testing.T) {
function compareStringSlices (line 359) | func compareStringSlices(t *testing.T, expected, actual []string) {
function TestParseSubject (line 374) | func TestParseSubject(t *testing.T) {
function TestCaptureErrors (line 431) | func TestCaptureErrors(t *testing.T) {
FILE: nrpcpb_test.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type DummyMessage (line 23) | type DummyMessage struct
method Reset (line 31) | func (x *DummyMessage) Reset() {
method String (line 40) | func (x *DummyMessage) String() string {
method ProtoMessage (line 44) | func (*DummyMessage) ProtoMessage() {}
method ProtoReflect (line 46) | func (x *DummyMessage) ProtoReflect() protoreflect.Message {
method Descriptor (line 59) | func (*DummyMessage) Descriptor() ([]byte, []int) {
method GetFoobar (line 63) | func (x *DummyMessage) GetFoobar() string {
function file_nrpc_test_proto_rawDescGZIP (line 87) | func file_nrpc_test_proto_rawDescGZIP() []byte {
function init (line 106) | func init() { file_nrpc_test_proto_init() }
function file_nrpc_test_proto_init (line 107) | func file_nrpc_test_proto_init() {
FILE: protoc-gen-nrpc/main.go
function baseName (line 21) | func baseName(name string) string {
function getGoPackage (line 35) | func getGoPackage(fd *descriptor.FileDescriptorProto) string {
function goPackageOption (line 54) | func goPackageOption(d *descriptor.FileDescriptorProto) (impPath, pkg st...
function goPackageName (line 80) | func goPackageName(d *descriptor.FileDescriptorProto) (name string, expl...
function goFileName (line 95) | func goFileName(d *descriptor.FileDescriptorProto) string {
function splitMessageTypeName (line 119) | func splitMessageTypeName(name string) (string, string) {
function splitTypePath (line 130) | func splitTypePath(name string) []string {
function lookupFileDescriptor (line 140) | func lookupFileDescriptor(name string) *descriptor.FileDescriptorProto {
function lookupMessageType (line 149) | func lookupMessageType(name string) (*descriptor.FileDescriptorProto, *d...
function getField (line 196) | func getField(d *descriptor.DescriptorProto, name string) *descriptor.Fi...
function getOneofDecl (line 205) | func getOneofDecl(d *descriptor.DescriptorProto, name string) *descripto...
function pkgSubject (line 214) | func pkgSubject(fd *descriptor.FileDescriptorProto) string {
function getResultType (line 224) | func getResultType(
function getGoType (line 230) | func getGoType(pbType string) (string, string) {
function getPkgImportName (line 240) | func getPkgImportName(goPkg string) string {
function main (line 404) | func main() {
FILE: protoc-gen-nrpc/tmpl.go
constant tFile (line 3) | tFile = `// This code was autogenerated from {{.GetName}}, do not edit.
FILE: testrunner_test.go
function TestMain (line 15) | func TestMain(m *testing.M) {
Condensed preview — 42 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (311K chars).
[
{
"path": ".gitignore",
"chars": 131,
"preview": "examples/helloworld/greeter_client/greeter_client\nexamples/helloworld/greeter_server/greeter_server\nexamples/alloptions/"
},
{
"path": ".travis.yml",
"chars": 436,
"preview": "language: go\n\ngo:\n - 1.13\n\nbefore_script:\n - curl -sSL https://github.com/google/protobuf/releases/download/v3.12.1/pr"
},
{
"path": "AUTHORS",
"chars": 46,
"preview": "RapidLoop, Inc.\nChristophe de Vienne, Orus.io\n"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 7190,
"preview": "# nRPC\n\n[](https://travis-ci.org/nats-rpc/nrpc)\n\nn"
},
{
"path": "alloptions_test.go",
"chars": 793,
"preview": "package nrpc\n\nimport (\n\t//\"bytes\"\n\t//\"os\"\n\t\"os/exec\"\n\t\"testing\"\n\t//\"time\"\n)\n\nfunc TestAllOptionsExample(t *testing.T) {\n"
},
{
"path": "examples/alloptions/alloptions.nrpc.go",
"chars": 26816,
"preview": "// This code was autogenerated from alloptions.proto, do not edit.\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"g"
},
{
"path": "examples/alloptions/alloptions.pb.go",
"chars": 12583,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc v4.22.2\n// sou"
},
{
"path": "examples/alloptions/alloptions.proto",
"chars": 1757,
"preview": "syntax = \"proto3\";\n\npackage main;\n\noption go_package = \".;main\";\n\nimport \"nrpc/nrpc.proto\";\n\noption (nrpc.packageSubject"
},
{
"path": "examples/alloptions/alloptions_test.go",
"chars": 14524,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gi"
},
{
"path": "examples/alloptions/main.go",
"chars": 3741,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n"
},
{
"path": "examples/alloptions/testrunner_test.go",
"chars": 586,
"preview": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\tnatsServer \"github."
},
{
"path": "examples/helloworld/greeter_client/main.go",
"chars": 766,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing th"
},
{
"path": "examples/helloworld/greeter_server/main.go",
"chars": 1435,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is t"
},
{
"path": "examples/helloworld/greeter_server/main_test.go",
"chars": 1150,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing "
},
{
"path": "examples/helloworld/greeter_server/testrunner_test.go",
"chars": 586,
"preview": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\tnatsServer \"github."
},
{
"path": "examples/helloworld/helloworld/helloworld.go",
"chars": 161,
"preview": "package helloworld\n\n//go:generate protoc -I. -I../../.. --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_op"
},
{
"path": "examples/helloworld/helloworld/helloworld.nrpc.go",
"chars": 4407,
"preview": "// This code was autogenerated from helloworld.proto, do not edit.\npackage helloworld\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time"
},
{
"path": "examples/helloworld/helloworld/helloworld.pb.go",
"chars": 7857,
"preview": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "examples/helloworld/helloworld/helloworld.proto",
"chars": 1195,
"preview": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "examples/metrics_helloworld/helloworld/helloworld.go",
"chars": 165,
"preview": "package helloworld\n\n//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out plugins=prometheus:. --nrp"
},
{
"path": "examples/metrics_helloworld/helloworld/helloworld.nrpc.go",
"chars": 7652,
"preview": "// This code was autogenerated from helloworld.proto, do not edit.\npackage helloworld\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time"
},
{
"path": "examples/metrics_helloworld/helloworld/helloworld.pb.go",
"chars": 7802,
"preview": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "examples/metrics_helloworld/helloworld/helloworld.proto",
"chars": 1181,
"preview": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use"
},
{
"path": "examples/metrics_helloworld/metrics_greeter_client/main.go",
"chars": 1141,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package contain"
},
{
"path": "examples/metrics_helloworld/metrics_greeter_server/main.go",
"chars": 1959,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github."
},
{
"path": "examples/nooption/nooption.go",
"chars": 142,
"preview": "package nooption\n\n//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_opt=paths=source_re"
},
{
"path": "examples/nooption/nooption.nrpc.go",
"chars": 4390,
"preview": "// This code was autogenerated from nooption.proto, do not edit.\npackage nooption\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t"
},
{
"path": "examples/nooption/nooption.pb.go",
"chars": 6665,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc v4.22.2\n// sou"
},
{
"path": "examples/nooption/nooption.proto",
"chars": 393,
"preview": "syntax = \"proto3\";\n\npackage nooption;\n\noption go_package = \"github.com/nats-rpc/nrpc/examples/nooption\";\n\nservice Greete"
},
{
"path": "go.mod",
"chars": 445,
"preview": "module github.com/nats-rpc/nrpc\n\ngo 1.11\n\nrequire (\n\tgithub.com/cespare/xxhash/v2 v2.2.0 // indirect\n\tgithub.com/golang/"
},
{
"path": "go.sum",
"chars": 55374,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
},
{
"path": "helloworld_test.go",
"chars": 2148,
"preview": "package nrpc\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"os/exec\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestHelloWorldExample(t *testing.T) {\n\t// ma"
},
{
"path": "nrpc.go",
"chars": 23144,
"preview": "package nrpc\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n"
},
{
"path": "nrpc.pb.go",
"chars": 24091,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc v4.22.2\n// sou"
},
{
"path": "nrpc.proto",
"chars": 1690,
"preview": "syntax = \"proto3\";\n\npackage nrpc;\n\noption go_package = \"github.com/nats-rpc/nrpc\";\n\nimport \"google/protobuf/descriptor.p"
},
{
"path": "nrpc_test.go",
"chars": 13342,
"preview": "package nrpc_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.g"
},
{
"path": "nrpc_test.proto",
"chars": 122,
"preview": "syntax = \"proto3\";\n\noption go_package = \"github.com/nats-rpc/nrpc_test\";\n\nmessage DummyMessage {\n string foobar = 1;\n"
},
{
"path": "nrpcpb_test.go",
"chars": 4235,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc v4.22.2\n// sou"
},
{
"path": "protoc-gen-nrpc/main.go",
"chars": 12527,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"github.com/nats-"
},
{
"path": "protoc-gen-nrpc/tmpl.go",
"chars": 20665,
"preview": "package main\n\nconst tFile = `// This code was autogenerated from {{.GetName}}, do not edit.\n\n{{- $pkgName := GoPackageNa"
},
{
"path": "testrunner_test.go",
"chars": 563,
"preview": "package nrpc\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\t\"github.com/nats-io"
}
]
About this extraction
This page contains the full source code of the rapidloop/nrpc GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 42 files (280.6 KB), approximately 106.9k tokens, and a symbol index with 369 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.