Full Code of rapidloop/nrpc for AI

master 8f47f6a864d1 cached
42 files
280.6 KB
106.9k tokens
369 symbols
1 requests
Download .txt
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

[![Build Status](https://travis-ci.org/nats-rpc/nrpc.svg?branch=master)](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).
Download .txt
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
Download .txt
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[![Build Status](https://travis-ci.org/nats-rpc/nrpc.svg?branch=master)](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.

Copied to clipboard!