veyron/runtimes/google/ipc/benchmarks: IPC benchmarks.
Adds a few benchmarks for the IPC code. Some initial numbers are in the
README file.
Change-Id: I1e06701b900e930d53ec911e3528f59d596d817c
diff --git a/runtimes/google/ipc/benchmarks/README.txt b/runtimes/google/ipc/benchmarks/README.txt
new file mode 100644
index 0000000..861911b
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/README.txt
@@ -0,0 +1,130 @@
+This directory contains code uses to measure the performance of the Veyron IPC
+stack.
+
+The ipc_test.go file uses GO's testing package to run benchmarks. Each
+benchmark involves one server and one client. The server has two very simple
+methods that echo the data received from the client back to the client.
+
+client ---- Echo(payload) ----> server
+client <--- return payload ---- server
+
+There are two versions of the Echo method:
+ - Echo(payload []byte) ([]byte], error)
+ - EchoStream() <[]byte,[]byte> error
+
+The first benchmarks use the non-streaming version of Echo with a varying
+payload size. The other benchmarks use the streaming version with varying
+number of chunks and payload sizes.
+
+All these benchmarks create a VC before measurements begin. So, the VC creation
+overhead is excluded.
+
+On a ThinkPad X1 Carbon (2 × Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz), we get:
+
+$ $VEYRON_ROOT/veyron/scripts/build/go test -test.bench=. -test.cpu=1 \
+ -test.benchtime=5s veyron/runtimes/google/ipc/benchmarks 2> /dev/null
+PASS
+Benchmark____1B 10000 545077 ns/op
+Benchmark___10B 10000 587312 ns/op
+Benchmark__100B 10000 523019 ns/op
+Benchmark___1KB 10000 605235 ns/op
+Benchmark__10KB 10000 957467 ns/op
+Benchmark_100KB 5000 4101891 ns/op
+Benchmark_N_RPCs____1_chunk_____1B 10000 554063 ns/op
+Benchmark_N_RPCs____1_chunk____10B 10000 551424 ns/op
+Benchmark_N_RPCs____1_chunk___100B 10000 538308 ns/op
+Benchmark_N_RPCs____1_chunk____1KB 10000 585579 ns/op
+Benchmark_N_RPCs____1_chunk___10KB 10000 904789 ns/op
+Benchmark_N_RPCs___10_chunks___1KB 10000 1460984 ns/op
+Benchmark_N_RPCs__100_chunks___1KB 1000 8491514 ns/op
+Benchmark_N_RPCs_1000_chunks___1KB 100 105269359 ns/op
+Benchmark_1_RPC_N_chunks_____1B 200000 763769 ns/op
+Benchmark_1_RPC_N_chunks____10B 100000 583134 ns/op
+Benchmark_1_RPC_N_chunks___100B 100000 80849 ns/op
+Benchmark_1_RPC_N_chunks____1KB 100000 88820 ns/op
+Benchmark_1_RPC_N_chunks___10KB 50000 361596 ns/op
+Benchmark_1_RPC_N_chunks__100KB 5000 3127193 ns/op
+ok veyron/runtimes/google/ipc/benchmarks 525.095s
+
+
+The Benchmark_Simple_____1KB line shows that it takes an average of 0.605 ms to
+execute a simple Echo RPC with a 1 KB payload.
+
+The Benchmark_N_RPCs____1_chunk____1KB line shows that a streaming RPC with the
+same payload (i.e. 1 chunk of 1 KB) takes about 0.586 ms on average.
+
+And Benchmark_1_RPC_N_chunks____1KB shows that sending a stream of 1 KB chunks
+takes an average of 0.088 ms per chunk.
+
+
+Running the client and server as separate processes.
+
+In this case, we can see the cost of name resolution, creating the VC, etc. in
+the first RPC.
+
+$ $VEYRON_ROOT/veyron/go/bin/bmserver --address=localhost:8888 --acl='{"*":"A"}'
+
+(In a different shell)
+$ $VEYRON_ROOT/veyron/go/bin/bmclient --server=/localhost:8888 --count=10 \
+ --payload_size=1000
+CallEcho 0 64133467
+CallEcho 1 766223
+CallEcho 2 703860
+CallEcho 3 697590
+CallEcho 4 601134
+CallEcho 5 601142
+CallEcho 6 624079
+CallEcho 7 644664
+CallEcho 8 605195
+CallEcho 9 637037
+
+It took about 64 ms to execute the first RPC, and then 0.60-0.70 ms to execute
+the next ones.
+
+
+On a Raspberry Pi, everything is much slower. The same tests show the following
+results:
+
+$ ./benchmarks.test -test.bench=. -test.cpu=1 -test.benchtime=5s 2>/dev/null
+PASS
+Benchmark____1B 500 21316148 ns/op
+Benchmark___10B 500 23304638 ns/op
+Benchmark__100B 500 21860446 ns/op
+Benchmark___1KB 500 24000346 ns/op
+Benchmark__10KB 200 37530575 ns/op
+Benchmark_100KB 100 136243310 ns/op
+Benchmark_N_RPCs____1_chunk_____1B 500 19957506 ns/op
+Benchmark_N_RPCs____1_chunk____10B 500 22868392 ns/op
+Benchmark_N_RPCs____1_chunk___100B 500 19635412 ns/op
+Benchmark_N_RPCs____1_chunk____1KB 500 22572190 ns/op
+Benchmark_N_RPCs____1_chunk___10KB 500 37570948 ns/op
+Benchmark_N_RPCs___10_chunks___1KB 100 51670740 ns/op
+Benchmark_N_RPCs__100_chunks___1KB 50 364938740 ns/op
+Benchmark_N_RPCs_1000_chunks___1KB 2 3586374500 ns/op
+Benchmark_1_RPC_N_chunks_____1B 10000 1034042 ns/op
+Benchmark_1_RPC_N_chunks____10B 5000 1894875 ns/op
+Benchmark_1_RPC_N_chunks___100B 5000 2857289 ns/op
+Benchmark_1_RPC_N_chunks____1KB 5000 6465839 ns/op
+Benchmark_1_RPC_N_chunks___10KB 100 80019430 ns/op
+Benchmark_1_RPC_N_chunks__100KB Killed
+
+The simple 1 KB RPCs take an average of 24 ms. The streaming equivalent takes
+about 22 ms, and streaming many 1 KB chunks takes about 6.5 ms per chunk.
+
+
+$ ./bmserver --address=localhost:8888 --acl='{"*":"A"}'
+
+$ ./bmclient --server=/localhost:8888 --count=10 --payload_size=1000
+CallEcho 0 2573406000
+CallEcho 1 44669000
+CallEcho 2 54442000
+CallEcho 3 33934000
+CallEcho 4 47985000
+CallEcho 5 61324000
+CallEcho 6 51654000
+CallEcho 7 47043000
+CallEcho 8 44995000
+CallEcho 9 53166000
+
+On the pi, the first RPC takes ~2.5 sec to execute.
+
diff --git a/runtimes/google/ipc/benchmarks/bmclient/main.go b/runtimes/google/ipc/benchmarks/bmclient/main.go
new file mode 100644
index 0000000..16c34c5
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/bmclient/main.go
@@ -0,0 +1,27 @@
+// a simple command-line tool to run the benchmark client.
+package main
+
+import (
+ "flag"
+ "os"
+
+ "veyron/runtimes/google/ipc/benchmarks"
+
+ "veyron2/rt"
+)
+
+var (
+ server = flag.String("server", "", "veyron name of the server to connect to")
+ count = flag.Int("count", 1, "number of RPCs to send")
+ chunkCount = flag.Int("chunk_count", 0, "number of stream chunks to send")
+ payloadSize = flag.Int("payload_size", 32, "the size of the payload")
+)
+
+func main() {
+ rt.Init()
+ if *chunkCount == 0 {
+ benchmarks.CallEcho(*server, *count, *payloadSize, os.Stdout)
+ } else {
+ benchmarks.CallEchoStream(*server, *count, *chunkCount, *payloadSize, os.Stdout)
+ }
+}
diff --git a/runtimes/google/ipc/benchmarks/bmserver/main.go b/runtimes/google/ipc/benchmarks/bmserver/main.go
new file mode 100644
index 0000000..017ad69
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/bmserver/main.go
@@ -0,0 +1,25 @@
+// a simple command-line tool to run the benchmark server.
+package main
+
+import (
+ "flag"
+
+ "veyron/lib/signals"
+ "veyron/runtimes/google/ipc/benchmarks"
+
+ "veyron2/rt"
+ "veyron2/vlog"
+)
+
+var (
+ address = flag.String("address", ":0", "address to listen on")
+ protocol = flag.String("protocol", "tcp", "protocol to listen on")
+)
+
+func main() {
+ rt.Init()
+ addr, stop := benchmarks.StartServer(*protocol, *address)
+ vlog.Infof("Listening on %s", addr)
+ defer stop()
+ <-signals.ShutdownOnSignals()
+}
diff --git a/runtimes/google/ipc/benchmarks/client.go b/runtimes/google/ipc/benchmarks/client.go
new file mode 100644
index 0000000..8117e8f
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/client.go
@@ -0,0 +1,101 @@
+package benchmarks
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "time"
+
+ "veyron2"
+ "veyron2/rt"
+ "veyron2/vlog"
+)
+
+// CallEcho calls the Echo method 'iterations' times with the given payload
+// size, and optionally logs the result.
+func CallEcho(address string, iterations, payloadSize int, log io.Writer) {
+ payload := make([]byte, payloadSize)
+ for _, i := range payload {
+ payload[i] = byte(i & 0xff)
+ }
+
+ stub, err := BindBenchmark(address)
+ if err != nil {
+ vlog.Fatalf("BindBenchmark(%q) failed: %v", address, err)
+ }
+
+ for i := 0; i < iterations; i++ {
+ start := time.Now()
+ result, err := stub.Echo(rt.R().TODOContext(), payload)
+ elapsed := time.Since(start)
+ if err != nil {
+ vlog.Fatalf("Echo failed: %v", err)
+ }
+ if !bytes.Equal(payload, result) {
+ vlog.Fatalf("Echo return different payload: got %v, expected %v", result, payload)
+ }
+ if log != nil {
+ log.Write([]byte(fmt.Sprintf("CallEcho %d %d\n", i, elapsed)))
+ }
+ }
+}
+
+// CallEchoStream calls the EchoStream method 'rpcCount' times. Each iteration
+// sends 'messageCount' messages on the stream and receives the same number
+// back. Each message has the given payload size. Optionally logs the result.
+func CallEchoStream(address string, rpcCount, messageCount, payloadSize int, log io.Writer) {
+ payload := make([]byte, payloadSize)
+ for _, i := range payload {
+ payload[i] = byte(i & 0xff)
+ }
+
+ stub, err := BindBenchmark(address)
+ if err != nil {
+ vlog.Fatalf("BindBenchmark(%q) failed: %v", address, err)
+ }
+
+ for i := 0; i < rpcCount; i++ {
+ start := time.Now()
+ stream, err := stub.EchoStream(rt.R().TODOContext(), veyron2.CallTimeout(time.Hour))
+ if err != nil {
+ vlog.Fatalf("EchoStream failed: %v", err)
+ }
+ done := make(chan error, 1)
+ go func() {
+ for {
+ chunk, err := stream.Recv()
+ if err == io.EOF {
+ done <- nil
+ return
+ }
+ if err != nil {
+ done <- err
+ return
+ }
+ if !bytes.Equal(payload, chunk) {
+ done <- fmt.Errorf("Recv got different payload: got %v, expected %v", chunk, payload)
+ return
+ }
+ }
+ }()
+ for j := 0; j < messageCount; j++ {
+ if err = stream.Send(payload); err != nil {
+ vlog.Fatalf("Send failed: %v", err)
+ }
+ }
+ if err = stream.CloseSend(); err != nil {
+ vlog.Fatalf("CloseSend() failed: %v", err)
+ }
+ if err = <-done; err != nil {
+ vlog.Fatalf("%v", err)
+ }
+
+ if err = stream.Finish(); err != nil {
+ vlog.Fatalf("Finish failed: %v", err)
+ }
+ elapsed := time.Since(start)
+ if log != nil {
+ log.Write([]byte(fmt.Sprintf("CallEchoStream %d %d\n", i, elapsed)))
+ }
+ }
+}
diff --git a/runtimes/google/ipc/benchmarks/ipc_test.go b/runtimes/google/ipc/benchmarks/ipc_test.go
new file mode 100644
index 0000000..411869f
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/ipc_test.go
@@ -0,0 +1,109 @@
+package benchmarks_test
+
+import (
+ "testing"
+
+ "veyron/runtimes/google/ipc/benchmarks"
+
+ "veyron2/rt"
+)
+
+func init() {
+ rt.Init()
+}
+
+func RunBenchmark(b *testing.B, payloadSize int) {
+ address, stop := benchmarks.StartServer("tcp", "127.0.0.1:0")
+ defer stop()
+ benchmarks.CallEcho(address, 1, 1, nil) // Create VC
+ b.ResetTimer()
+ benchmarks.CallEcho(address, b.N, payloadSize, nil)
+}
+
+func RunStreamBenchmark(b *testing.B, rpcCount, messageCount, payloadSize int) {
+ address, stop := benchmarks.StartServer("tcp", "127.0.0.1:0")
+ defer stop()
+ benchmarks.CallEchoStream(address, 1, 1, 1, nil) // Create VC
+ b.ResetTimer()
+ benchmarks.CallEchoStream(address, rpcCount, messageCount, payloadSize, nil)
+}
+
+func Benchmark____1B(b *testing.B) {
+ RunBenchmark(b, 1)
+}
+
+func Benchmark___10B(b *testing.B) {
+ RunBenchmark(b, 10)
+}
+
+func Benchmark__100B(b *testing.B) {
+ RunBenchmark(b, 100)
+}
+
+func Benchmark___1KB(b *testing.B) {
+ RunBenchmark(b, 1000)
+}
+
+func Benchmark__10KB(b *testing.B) {
+ RunBenchmark(b, 10000)
+}
+
+func Benchmark_100KB(b *testing.B) {
+ RunBenchmark(b, 100000)
+}
+
+func Benchmark_N_RPCs____1_chunk_____1B(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1, 1)
+}
+
+func Benchmark_N_RPCs____1_chunk____10B(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1, 10)
+}
+
+func Benchmark_N_RPCs____1_chunk___100B(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1, 100)
+}
+
+func Benchmark_N_RPCs____1_chunk____1KB(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1, 1000)
+}
+
+func Benchmark_N_RPCs____1_chunk___10KB(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1, 10000)
+}
+
+func Benchmark_N_RPCs___10_chunks___1KB(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 10, 1000)
+}
+
+func Benchmark_N_RPCs__100_chunks___1KB(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 100, 1000)
+}
+
+func Benchmark_N_RPCs_1000_chunks___1KB(b *testing.B) {
+ RunStreamBenchmark(b, b.N, 1000, 1000)
+}
+
+func Benchmark_1_RPC_N_chunks_____1B(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 1)
+}
+
+func Benchmark_1_RPC_N_chunks____10B(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 10)
+}
+
+func Benchmark_1_RPC_N_chunks___100B(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 100)
+}
+
+func Benchmark_1_RPC_N_chunks____1KB(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 1000)
+}
+
+func Benchmark_1_RPC_N_chunks___10KB(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 10000)
+}
+
+func Benchmark_1_RPC_N_chunks__100KB(b *testing.B) {
+ RunStreamBenchmark(b, 1, b.N, 100000)
+}
diff --git a/runtimes/google/ipc/benchmarks/server.go b/runtimes/google/ipc/benchmarks/server.go
new file mode 100644
index 0000000..d585d72
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/server.go
@@ -0,0 +1,57 @@
+package benchmarks
+
+import (
+ "io"
+
+ sflag "veyron/security/flag"
+
+ "veyron2/ipc"
+ "veyron2/naming"
+ "veyron2/rt"
+ "veyron2/vlog"
+)
+
+type impl struct {
+}
+
+func (i *impl) Echo(ctx ipc.ServerContext, payload []byte) ([]byte, error) {
+ return payload, nil
+}
+
+func (i *impl) EchoStream(ctx ipc.ServerContext, stream BenchmarkServiceEchoStreamStream) error {
+ for {
+ chunk, err := stream.Recv()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ if err := stream.Send(chunk); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// StartServer starts a server that implements the Benchmark service. The
+// server listens to the given protocol and address, and returns the veyron
+// address of the server and a callback function to stop the server.
+func StartServer(protocol, address string) (string, func()) {
+ server, err := rt.R().NewServer()
+ if err != nil {
+ vlog.Fatalf("NewServer failed: %v", err)
+ }
+ if err := server.Register("", ipc.SoloDispatcher(NewServerBenchmark(&impl{}), sflag.NewAuthorizerOrDie())); err != nil {
+ vlog.Fatalf("Register failed: %v", err)
+ }
+ ep, err := server.Listen(protocol, address)
+ if err != nil {
+ vlog.Fatalf("Listen failed: %v", err)
+ }
+ return naming.JoinAddressName(ep.String(), ""), func() {
+ if err := server.Stop(); err != nil {
+ vlog.Fatalf("Stop() failed: %v", err)
+ }
+ }
+}
diff --git a/runtimes/google/ipc/benchmarks/service.vdl b/runtimes/google/ipc/benchmarks/service.vdl
new file mode 100644
index 0000000..ad0afcf
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/service.vdl
@@ -0,0 +1,10 @@
+// package benchmark provides simple tools to measure the performance of the
+// IPC system.
+package benchmarks
+
+type Benchmark interface {
+ // Echo returns the payload that it receives.
+ Echo(Payload []byte) ([]byte, error)
+ // EchoStream returns the payload that it receives via the stream.
+ EchoStream() stream<[]byte,[]byte> error
+}
diff --git a/runtimes/google/ipc/benchmarks/service.vdl.go b/runtimes/google/ipc/benchmarks/service.vdl.go
new file mode 100644
index 0000000..371285d
--- /dev/null
+++ b/runtimes/google/ipc/benchmarks/service.vdl.go
@@ -0,0 +1,293 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: service.vdl
+
+// package benchmark provides simple tools to measure the performance of the
+// IPC system.
+package benchmarks
+
+import (
+ // The non-user imports are prefixed with "_gen_" to prevent collisions.
+ _gen_veyron2 "veyron2"
+ _gen_context "veyron2/context"
+ _gen_ipc "veyron2/ipc"
+ _gen_naming "veyron2/naming"
+ _gen_rt "veyron2/rt"
+ _gen_vdl "veyron2/vdl"
+ _gen_wiretype "veyron2/wiretype"
+)
+
+// Benchmark is the interface the client binds and uses.
+// Benchmark_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions. Not to be used directly by clients.
+type Benchmark_ExcludingUniversal interface {
+ // Echo returns the payload that it receives.
+ Echo(ctx _gen_context.T, Payload []byte, opts ..._gen_ipc.CallOpt) (reply []byte, err error)
+ // EchoStream returns the payload that it receives via the stream.
+ EchoStream(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply BenchmarkEchoStreamStream, err error)
+}
+type Benchmark interface {
+ _gen_ipc.UniversalServiceMethods
+ Benchmark_ExcludingUniversal
+}
+
+// BenchmarkService is the interface the server implements.
+type BenchmarkService interface {
+
+ // Echo returns the payload that it receives.
+ Echo(context _gen_ipc.ServerContext, Payload []byte) (reply []byte, err error)
+ // EchoStream returns the payload that it receives via the stream.
+ EchoStream(context _gen_ipc.ServerContext, stream BenchmarkServiceEchoStreamStream) (err error)
+}
+
+// BenchmarkEchoStreamStream is the interface for streaming responses of the method
+// EchoStream in the service interface Benchmark.
+type BenchmarkEchoStreamStream interface {
+
+ // Send places the item onto the output stream, blocking if there is no buffer
+ // space available.
+ Send(item []byte) error
+
+ // CloseSend indicates to the server that no more items will be sent; server
+ // Recv calls will receive io.EOF after all sent items. Subsequent calls to
+ // Send on the client will fail. This is an optional call - it's used by
+ // streaming clients that need the server to receive the io.EOF terminator.
+ CloseSend() error
+
+ // Recv returns the next item in the input stream, blocking until
+ // an item is available. Returns io.EOF to indicate graceful end of input.
+ Recv() (item []byte, err error)
+
+ // Finish closes the stream and returns the positional return values for
+ // call.
+ Finish() (err error)
+
+ // Cancel cancels the RPC, notifying the server to stop processing.
+ Cancel()
+}
+
+// Implementation of the BenchmarkEchoStreamStream interface that is not exported.
+type implBenchmarkEchoStreamStream struct {
+ clientCall _gen_ipc.Call
+}
+
+func (c *implBenchmarkEchoStreamStream) Send(item []byte) error {
+ return c.clientCall.Send(item)
+}
+
+func (c *implBenchmarkEchoStreamStream) CloseSend() error {
+ return c.clientCall.CloseSend()
+}
+
+func (c *implBenchmarkEchoStreamStream) Recv() (item []byte, err error) {
+ err = c.clientCall.Recv(&item)
+ return
+}
+
+func (c *implBenchmarkEchoStreamStream) Finish() (err error) {
+ if ierr := c.clientCall.Finish(&err); ierr != nil {
+ err = ierr
+ }
+ return
+}
+
+func (c *implBenchmarkEchoStreamStream) Cancel() {
+ c.clientCall.Cancel()
+}
+
+// BenchmarkServiceEchoStreamStream is the interface for streaming responses of the method
+// EchoStream in the service interface Benchmark.
+type BenchmarkServiceEchoStreamStream interface {
+ // Send places the item onto the output stream, blocking if there is no buffer
+ // space available.
+ Send(item []byte) error
+
+ // Recv fills itemptr with the next item in the input stream, blocking until
+ // an item is available. Returns io.EOF to indicate graceful end of input.
+ Recv() (item []byte, err error)
+}
+
+// Implementation of the BenchmarkServiceEchoStreamStream interface that is not exported.
+type implBenchmarkServiceEchoStreamStream struct {
+ serverCall _gen_ipc.ServerCall
+}
+
+func (s *implBenchmarkServiceEchoStreamStream) Send(item []byte) error {
+ return s.serverCall.Send(item)
+}
+
+func (s *implBenchmarkServiceEchoStreamStream) Recv() (item []byte, err error) {
+ err = s.serverCall.Recv(&item)
+ return
+}
+
+// BindBenchmark returns the client stub implementing the Benchmark
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindBenchmark(name string, opts ..._gen_ipc.BindOpt) (Benchmark, error) {
+ var client _gen_ipc.Client
+ switch len(opts) {
+ case 0:
+ client = _gen_rt.R().Client()
+ case 1:
+ switch o := opts[0].(type) {
+ case _gen_veyron2.Runtime:
+ client = o.Client()
+ case _gen_ipc.Client:
+ client = o
+ default:
+ return nil, _gen_vdl.ErrUnrecognizedOption
+ }
+ default:
+ return nil, _gen_vdl.ErrTooManyOptionsToBind
+ }
+ stub := &clientStubBenchmark{client: client, name: name}
+
+ return stub, nil
+}
+
+// NewServerBenchmark creates a new server stub.
+//
+// It takes a regular server implementing the BenchmarkService
+// interface, and returns a new server stub.
+func NewServerBenchmark(server BenchmarkService) interface{} {
+ return &ServerStubBenchmark{
+ service: server,
+ }
+}
+
+// clientStubBenchmark implements Benchmark.
+type clientStubBenchmark struct {
+ client _gen_ipc.Client
+ name string
+}
+
+func (__gen_c *clientStubBenchmark) Echo(ctx _gen_context.T, Payload []byte, opts ..._gen_ipc.CallOpt) (reply []byte, err error) {
+ var call _gen_ipc.Call
+ if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Echo", []interface{}{Payload}, opts...); err != nil {
+ return
+ }
+ if ierr := call.Finish(&reply, &err); ierr != nil {
+ err = ierr
+ }
+ return
+}
+
+func (__gen_c *clientStubBenchmark) EchoStream(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply BenchmarkEchoStreamStream, err error) {
+ var call _gen_ipc.Call
+ if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "EchoStream", nil, opts...); err != nil {
+ return
+ }
+ reply = &implBenchmarkEchoStreamStream{clientCall: call}
+ return
+}
+
+func (__gen_c *clientStubBenchmark) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+ var call _gen_ipc.Call
+ if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+ return
+ }
+ if ierr := call.Finish(&reply, &err); ierr != nil {
+ err = ierr
+ }
+ return
+}
+
+func (__gen_c *clientStubBenchmark) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+ var call _gen_ipc.Call
+ if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+ return
+ }
+ if ierr := call.Finish(&reply, &err); ierr != nil {
+ err = ierr
+ }
+ return
+}
+
+func (__gen_c *clientStubBenchmark) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+ var call _gen_ipc.Call
+ if call, err = __gen_c.client.StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+ return
+ }
+ if ierr := call.Finish(&reply, &err); ierr != nil {
+ err = ierr
+ }
+ return
+}
+
+// ServerStubBenchmark wraps a server that implements
+// BenchmarkService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubBenchmark struct {
+ service BenchmarkService
+}
+
+func (__gen_s *ServerStubBenchmark) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+ // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+ // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+ // This will change when it is replaced with Signature().
+ switch method {
+ case "Echo":
+ return []interface{}{}, nil
+ case "EchoStream":
+ return []interface{}{}, nil
+ default:
+ return nil, nil
+ }
+}
+
+func (__gen_s *ServerStubBenchmark) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+ result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+ result.Methods["Echo"] = _gen_ipc.MethodSignature{
+ InArgs: []_gen_ipc.MethodArgument{
+ {Name: "Payload", Type: 66},
+ },
+ OutArgs: []_gen_ipc.MethodArgument{
+ {Name: "", Type: 66},
+ {Name: "", Type: 67},
+ },
+ }
+ result.Methods["EchoStream"] = _gen_ipc.MethodSignature{
+ InArgs: []_gen_ipc.MethodArgument{},
+ OutArgs: []_gen_ipc.MethodArgument{
+ {Name: "", Type: 67},
+ },
+ InStream: 66,
+ OutStream: 66,
+ }
+
+ result.TypeDefs = []_gen_vdl.Any{
+ _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x41, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
+
+ return result, nil
+}
+
+func (__gen_s *ServerStubBenchmark) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+ if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+ return unresolver.UnresolveStep(call)
+ }
+ if call.Server() == nil {
+ return
+ }
+ var published []string
+ if published, err = call.Server().Published(); err != nil || published == nil {
+ return
+ }
+ reply = make([]string, len(published))
+ for i, p := range published {
+ reply[i] = _gen_naming.Join(p, call.Name())
+ }
+ return
+}
+
+func (__gen_s *ServerStubBenchmark) Echo(call _gen_ipc.ServerCall, Payload []byte) (reply []byte, err error) {
+ reply, err = __gen_s.service.Echo(call, Payload)
+ return
+}
+
+func (__gen_s *ServerStubBenchmark) EchoStream(call _gen_ipc.ServerCall) (err error) {
+ stream := &implBenchmarkServiceEchoStreamStream{serverCall: call}
+ err = __gen_s.service.EchoStream(call, stream)
+ return
+}