Code Monkey home page Code Monkey logo

yab's Introduction

yab Build Status Coverage Status

yab (Yet Another Benchmarker) is a tool to benchmark YARPC services. It currently supports making Thrift requests to both HTTP and TChannel services, as well as Protobuf requests to gRPC services.

yab is currently in beta status.

Installing

If you have go installed, simply run the following to install the latest version:

GO111MODULE=on go get -u github.com/yarpc/yab

This will install yab to $GOPATH/bin/yab.

Optionally, you can get precompiled binaries from Releases.

Usage

Usage:
  yab [<service> <method> <body>] [OPTIONS]

yab is a benchmarking tool for TChannel and HTTP applications. It's primarily
intended for Thrift applications but supports other encodings like JSON and
binary (raw). It can be used in a curl-like fashion when benchmarking features
are disabled.

yab includes a full man page (man yab), which is also available online:
http://yarpc.github.io/yab/man.html


Application Options:
  -v                             Enable more detailed logging. Repeats increase
                                 the verbosity, ie. -vvv
      --version                  Displays the application version

Request Options:
  -e, --encoding=                The encoding of the data, options are: Thrift,
                                 proto, JSON, raw. Defaults to Thrift if the
                                 method contains '::' or a Thrift file is
                                 specified. Defaults to proto if the method
                                 contains '/' or a proto filedescriptorset is
                                 specified
  -t, --thrift=                  Path of the .thrift file
  -F, --file-descriptor-set-bin= A binary file containing a compiled protobuf
                                 FileDescriptorSet.
      --procedure=               The full method name to invoke (Thrift:
                                 Svc::Method, Proto: package.Service/Method).
  -m, --method=                  Alias for procedure
  -r, --request=                 The request body, in JSON or YAML format
  -f, --file=                    Path of a file containing the request body in
                                 JSON or YAML
  -H, --header=                  Individual application header as a key:value
                                 pair per flag
      --headers=                 The headers in JSON or YAML format
      --headers-file=            Path of a file containing the headers in JSON
                                 or YAML
  -B, --baggage=                 Individual context baggage header as a
                                 key:value pair per flag
      --health                   Hit the health endpoint, Meta::health
      --timeout=                 The timeout for each request. E.g., 100ms,
                                 0.5s, 1s. If no unit is specified,
                                 milliseconds are assumed. (default: 1s)
  -y, --yaml-template=           Send a tchannel request specified by a YAML
                                 template
  -A, --arg=                     A list of key-value template arguments,
                                 specified as -A foo:bar -A user:me
      --disable-thrift-envelope  Disables Thrift envelopes (disabled by default
                                 for TChannel and gRPC)
      --multiplexed-thrift       Enables the Thrift TMultiplexedProtocol used
                                 by services that host multiple Thrift services
                                 on a single endpoint.
      --stream-interval=         Interval between consecutive stream message sends,
                                 applicable separately to every stream request
                                 opened on a connection.
      --stream-delay-close-send= Delay the closure of send stream once all the
                                 request messages have been sent.

Transport Options:
  -s, --service=                 The TChannel/Hyperbahn service name
  -p, --peer=                    The host:port of the service to call
  -P, --peer-list=               Path or URL of a JSON, YAML, or flat file
                                 containing a list of host:ports. -P? for
                                 supported protocols.
      --caller=                  Caller will override the default caller name
                                 (which is yab-$USER).
      --rk=                      The routing key overrides the service name
                                 traffic group for proxies.
      --rd=                      The routing delegate overrides the routing key
                                 traffic group for proxies.
      --sk=                      The shard key is a transport header that clues
                                 where to send a request within a clustered
                                 traffic group.
      --jaeger                   Use the Jaeger tracing client to send Uber
                                 style traces and baggage headers
      --force-jaeger-sample      If Jaeger tracing is enabled with --jaeger, force all requests
                                 to be sampled.
  -T, --topt=                    Transport options for TChannel, protocol
                                 headers for HTTP
      --http-method=             The HTTP method to use (default: POST)
      --grpc-max-response-size=  Maximum response size for gRPC requests. Default value is 4MB

Benchmark Options:
  -n, --max-requests=            The maximum number of requests to make. 0
                                 implies no limit. (default: 0)
  -d, --max-duration=            The maximum amount of time to run the
                                 benchmark for. 0 implies no duration limit.
                                 (default: 0s)
      --cpus=                    The number of OS threads
      --connections=             The number of TCP connections to use
      --warmup=                  The number of requests to make to warmup each
                                 connection (default: 10)
      --concurrency=             The number of concurrent calls per connection
                                 (default: 1)
      --rps=                     Limit on the number of requests per second.
                                 The default (0) is no limit. (default: 0)
      --statsd=                  Optional host:port of a StatsD server to
                                 report metrics
      --per-peer-stats           Whether to emit stats by peer rather than
                                 aggregated

Help Options:
  -h, --help                     Show this help message

Making a single request

Thrift

The following examples assume that the Thrift service running looks like:

service KeyValue {
  string get(1: string key)
}

If a TChannel service was running with name keyvalue on localhost:12345, you can make a call to the get method by running:

yab -t ~/keyvalue.thrift -p localhost:12345 keyvalue KeyValue::get -r '{"key": "hello"}'

Proto

The following examples assume that the Proto service running looks like:

service KeyValue {
  rpc GetValue(Request) returns (Response) {}
  rpc GetValueStream(stream Request) returns (stream Response) {}
}

message Request {
    required string key = 1;
}

message Response {
    required string value = 1;
}

If a gRPC service was running with name KeyValue on localhost:12345 with proto package name pkg.keyvalue and binary file containing a compiled protobuf FileDescriptorSet as keyValue.proto.bin, you can make a call to the GetValue method by running:

yab keyvalue pkg.keyvalue/GetValue --file-descriptor-set-bin=keyValue.proto.bin -r '{"key": "hello"}' -p localhost:12345

You can make a call to the bi-directional stream method GetValueStream with multiple requests by running:

yab keyvalue pkg.keyvalue/GetValueStream --file-descriptor-set-bin=keyValue.proto.bin -r '{"key": "hello1"} {"key": "hello2"}' -p localhost:12345

You can also interactively pass request data (JSON or YAML) on STDIN to the bi-directional stream method GetValueStream by setting option -request='-':

yab keyvalue pkg.keyvalue/GetValueStream --file-descriptor-set-bin=keyValue.proto.bin -r '-' -p localhost:12345

{"key": "hello1"} // STDIN request-1
{...} //Response-1

{"key": "hello2"} // STDIN request-2
{...} //Response-2

Note: YAML requests on STDIN must be delimited by --- and followed by a newline.

Protobuf FileDescriptorSet can be generated by running:

protoc --include_imports --descriptor_set_out=keyValue.proto.bin keyValue.proto

Note : If Server Reflection is enabled which provides information about publicly-accessible gRPC services on a server, then there is no need to specify the FileDescriptorSet binary:

yab keyvalue pkg.keyvalue/GetValue -r '{"key": "hello"} -p localhost:12345'

Specifying Peers

A single host:port is specified using -p, but you can also specify multiple peers by passing the -p flag multiple times:

yab -t ~/keyvalue.thrift -p localhost:12345 -p localhost:12346 keyvalue KeyValue::get -r '{"key": "hello"}'
yab keyvalue pkg.keyvalue/GetValue -r '{"key": "hello"} -p localhost:12345 -p localhost:12346'

If you have a file containing a list of host:ports (either JSON or new line separated), you can specify the file using -P:

yab -t ~/keyvalue.thrift -P ~/hosts.json keyvalue KeyValue::get -r '{"key": "hello"}'
yab keyvalue pkg.keyvalue/GetValue -r '{"key": "hello"} -P ~/hosts.json'

yab also supports HTTP, instead of the peer being a single host:port, you would use a URL:

yab -t ~/keyvalue.thrift -p "http://localhost:8080/rpc" keyvalue KeyValue::get -r '{"key": "hello"}'

Benchmarking

To benchmark an endpoint, you need all the command line arguments to describe the request, followed by benchmarking options. You need to set at least --maxDuration (or -d) to set the maximum amount of time to run the benchmark.

You can set values such as 3s for 3 seconds, or 1m for 1 minute. Valid time units are:

  • ms for milliseconds
  • s for seconds
  • m for minutes.

You can also control rate limit the benchmark (--rps), or customize the number of connections (--connections) or control the amount of concurrent calls per connection (--concurrency).

yab -t ~/keyvalue.thrift -p localhost:12345 keyvalue KeyValue::get -r '{"key": "hello"}' -d 5s --rps 100 --connections 4

In a gRPC stream method benchmark, a stream benchmark request is considered successful when a stream sends all the requests and receives response messages successfully. Example stream benchmark command and output:

> yab keyvalue pkg.keyvalue/GetValueStream -r '{"key": "hello1"} {"key": "hello2"}' -p localhost:12345 --duration=1s

Benchmark parameters:
  CPUs:            12
  Connections:     24
  Concurrency:     1
  Max requests:    10000
  Max duration:    1s
  Max RPS:         0
Latencies:
  0.5000: 779.01µs
  0.9000: 2.034852ms
  0.9500: 2.932846ms
  0.9900: 11.698821ms
  0.9990: 15.839751ms
  0.9995: 16.651223ms
  1.0000: 17.198644ms
Elapsed time (seconds):         0.49
Total requests:                 10000
RPS:                            20190.25
Total stream messages sent:     20000
Total stream messages received: 20000

yab's People

Contributors

abhinav avatar allenluuber avatar alshopov avatar apty avatar billf avatar biosvs avatar blampe avatar bufdev avatar dependabot[bot] avatar eklitzke avatar gandhikrishna avatar isaachier avatar jakobgt avatar jaricftw avatar jeffbean avatar jquirke avatar jronak avatar kriskowal avatar nikolavp avatar nishakhater avatar prashantv avatar robbertvanginkel avatar witriew avatar zymoticb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yab's Issues

add "sk" tchannel header support

This could be a hidden option. Sorry if we already support this -- it looks like it might fit into --topt but I didn't dig in.

Support routing key and routing delegate

We’ve recently added support for TChannel and HTTP routing keys and routing delegates. We should expose these with flags.

For TChannel, we will need to upgrade, then use the call options for RoutingDelegate and RoutingKey.

For HTTP, the corresponding headers are Rpc-Routing-Delegate and Rpc-Reouting-Key.

Update yab to use the latest thriftrw-go

Currently, you can't go get yab since we're using an older version of the thriftrw-go API.

See errors:

# github.com/yarpc/yab/thrift
../../../github.com/yarpc/yab/thrift/from_wire.go:75: undefined: wire.List
../../../github.com/yarpc/yab/thrift/from_wire.go:77: too many arguments in call to wire.ValueListToSlice
../../../github.com/yarpc/yab/thrift/from_wire.go:88: undefined: wire.Set
../../../github.com/yarpc/yab/thrift/from_wire.go:92: undefined: wire.List
../../../github.com/yarpc/yab/thrift/from_wire.go:95: undefined: wire.Map
../../../github.com/yarpc/yab/thrift/from_wire.go:97: too many arguments in call to wire.MapItemListToSlice
../../../github.com/yarpc/yab/thrift/to_wire.go:76: undefined: wire.List
../../../github.com/yarpc/yab/thrift/to_wire.go:79: undefined: wire.List
../../../github.com/yarpc/yab/thrift/to_wire.go:86: undefined: wire.List
../../../github.com/yarpc/yab/thrift/to_wire.go:132: undefined: wire.Map
../../../github.com/yarpc/yab/thrift/to_wire.go:86: too many errors

Support plugins for resolving custom URLs to a list of peers

Today, -p specifies a single peer, and for HTTP also happens to specify the URL template for the request including the protocol scheme of choice as well as the path. -P specifies a peer list, currently only supporting a file in YAML or JSON or flat text format. We propose to extend -P to accept a URI with multiple supported protocols including file: (to explicate the current behavior), and add http: to support grabbing the content via an HTTP request, and allow registering alternate protocols.

I think the right solution is to use the plugin support in go1.8 to load plugins that can provide custom peer providers.

type PeerProvider interface {
	Schemes() []string
	Resolve(context.Context, *url.URL) ([]string, error)
}

Resolve returns an array of alternative flags for -p, which over HTTP continues to serve as the URL template and can be used in combination with -P. In the absence of a provided -p, the selected peer template string is used both for the address and the template.

$ yab -P alt://blah/blah:http --health

Resolve payload paths relative to base directory

Currently the JSON to Thrift interpreter accepts file for strings and binary blobs, to read a file. It currently uses the working directory as the base directory for that path. This should be relative to the YAML base directory when used with -y. We need to thread the base directory through the JSON to Thrift marshaller.

Build fails

I'm getting the following after running this.

go get -u -f github.com/yarpc/yab

package github.com/yarpc/yab
    imports github.com/yarpc/yab/encoding
    imports github.com/yarpc/yab/thrift
    imports github.com/thriftrw/thriftrw-go/envelope
    imports go.uber.org/thriftrw/internal/envelope/exception: use of internal package not allowed

yab: HTTP does not respect timeouts

Currently, the timeout in the context is used to set the timeout header, but we're not setting the context on the request, and letting Go handle timeouts for us.

Support arguments to yaml templates

We often have common queries (either for testing, or administration) that have some parameters.

It would be nice if we could use a YAML template and parameterize parts of it (e.g., the service name, or some part of the request body).

E.g., if --health didn't exist, we might have a yaml template like:

#!/usr/bin/yab -y

service: $service
thrift: ./idl/meta.health
procedure: Meta::health
body:
  user: ${user:prashant}

And we could do ./health.yaml --arg service:foo --arg user:foo

support for varying requests in benchmarks

Right now we only take one body and duplicate it for every request within a benchmark. @ZymoticB pointed out that it's sometimes useful to benchmark different request bodies concurrently, and I wanted to open up a conversation around whether we could (or should) support something like that.

Concretely, this means something like "I want half of my benchmark's requests to use a body FOO and the other half to use BAR."

I was thinking we might be able to support a directory argument, and each file therein would be interpreted as a unique request body. With a heuristic like "append .headers to the request's filename" we could also attach per-request headers. This would leave a directory structure like so:

requests/
    foo
    foo.headers
    bar

$ yab --requests=./requests ...

This would cause yab to round-robin between foo and bar; and foo would override headers provided on the CLI.

The user could then control the distribution of requests with this file structure. For example if I want 2/3 of requests to be FOO and 1/3 to be BAR I would simply drop FOO.1 and FOO.2 into the directory.

Thoughts?

Support opentracing baggage

We now have standard ways to transport opentracing baggage with HTTP and TChannel. We should expose a --baggage flag that threads the appropriate headers for each transport.

We may need to also provide a way to configure the opentracing baggage prefix, both on the CLI and through yabrc.

Block "tcurl" callers

People use the --caller option to emulate tcurl's caller name, but this masks who is actually making the call. Let's prevent it.

Default help output and --help differ

This seems to violate POLA.

% diff -u =(yab) =(yab --help)
--- /tmp/zshqZl9Ex	2016-11-29 00:12:26.692863270 +0000
+++ /tmp/zshJIFTy8	2016-11-29 00:12:26.700863481 +0000
@@ -19,14 +19,14 @@
       --headers-file=            Path of a file containing the headers in JSON or YAML
   -B, --baggage=                 Individual context baggage header as a key:value pair per flag
       --health                   Hit the health endpoint, Meta::health
-      --timeout=                 The timeout for each request. E.g., 100ms, 0.5s, 1s. If no unit is specified, milliseconds are assumed.
+      --timeout=                 The timeout for each request. E.g., 100ms, 0.5s, 1s. If no unit is specified, milliseconds are assumed. (default: 1s)
       --disable-thrift-envelope  Disables Thrift envelopes (disabled by default for TChannel)
       --multiplexed-thrift       Enables the Thrift TMultiplexedProtocol used by services that host multiple Thrift services on a single endpoint.

 Transport Options:
   -s, --service=                 The TChannel/Hyperbahn service name
   -p, --peer=                    The host:port of the service to call
-  -P, --peer-list=               Path of a JSON or YAML file containing a list of host:ports
+  -P, --peer-list=               Path of a JSON or YAML file containing a list of host:ports (default: /path/to/hosts/file)
       --caller=                  Caller will override the default caller name (which is yab-$USER).
       --rk=                      The routing key overrides the service name traffic group for proxies.
       --rd=                      The routing delegate overrides the routing key traffic group for proxies.
@@ -35,11 +35,14 @@
   -T, --topt=                    Transport options for TChannel, protocol headers for HTTP

 Benchmark Options:
-  -n, --max-requests=            The maximum number of requests to make. 0 implies no limit.
-  -d, --max-duration=            The maximum amount of time to run the benchmark for. 0 implies no duration limit.
+  -n, --max-requests=            The maximum number of requests to make. 0 implies no limit. (default: 0)
+  -d, --max-duration=            The maximum amount of time to run the benchmark for. 0 implies no duration limit. (default: 0s)
       --cpus=                    The number of OS threads
       --connections=             The number of TCP connections to use
-      --warmup=                  The number of requests to make to warmup each connection
-      --concurrency=             The number of concurrent calls per connection
-      --rps=                     Limit on the number of requests per second. The default (0) is no limit.
+      --warmup=                  The number of requests to make to warmup each connection (default: 10)
+      --concurrency=             The number of concurrent calls per connection (default: 1)
+      --rps=                     Limit on the number of requests per second. The default (0) is no limit. (default: 0)
       --statsd=                  Optional host:port of a StatsD server to report metrics
+
+Help Options:
+  -h, --help                     Show this help message

Failing to parse default ini file

cat ~/.config/yab/defaults.ini
[request]
timeout = 2s
[benchmark]
warmup = 10

$ yab [...]
Failed to parse options: error reading defaults: couldn't read /home/abeinstein/.config/yab/defaults.ini: could not find option group `request'

cc @abeinstein

HTTP/Enveloping: Support TMultiplexedProtocol

yab currently does not support TMultiplexedProtocol for HTTP/Thrift services. The only difference is that instead of using the $methodName in the envelope, it will use $serviceName$delimiter$methodName, where $delimiter is configurable and it defaults to :.

Prefix application headers over HTTP

yab does not currently prefix application headers with Rpc-Header- over HTTP. I propose that we repurpose TOpts --topts for raw HTTP headers and alias that with -T, so -T for transport headers, -H for application headers, -B for baggage headers.

yab fails to warmup with tchannel error ErrCodeBusy

yab --rps 1 -d 5s {$QUERY_PARAMS}

Error message:

Failed to warmup connections for benchmark: tchannel error ErrCodeBusy: {SERVICE_NAME} is rate-limited by the service rps of 100

yab --rps 1 -d 5s --warmup 0 {$QUERY_PARAMS} can bypass this error.

When using -d duration and --rps the time to do a test is not the specified duration

Two examples of this that show the correlation,

[bean@staging02 ~/yab] (master)$ ./yab-linux-amd64 moe --health -d 5s -p staging02:21300 --connections=100 --concurrency=2 --rps=100
{
  "body": {
    "result": {
      "ok": true
    }
  },
  "trace": "49a9f05c8f3f7cd4"
}

Benchmark parameters:
  CPUs:            24
  Connections:     100
  Concurrency:     2
  Max requests:    1000000
  Max duration:    5s
  Max RPS:         100
Latencies:
  0.5000: 1.138842ms
  0.9000: 1.573129ms
  0.9500: 2.976241ms
  0.9900: 13.437581ms
  0.9990: 29.176007ms
  0.9995: 31.255959ms
  1.0000: 33.335911ms
Elapsed time:      6.99s
Total requests:    500
RPS:               71.53
[bean@staging02 ~/yab] (master)$ time ./yab-linux-amd64 moe --health -d 5s -p staging02:21300 --connections=100 --concurrency=2 --rps=10
{
  "body": {
    "result": {
      "ok": true
    }
  },
  "trace": "5cbdf15a54eadb07"
}

Benchmark parameters:
  CPUs:            24
  Connections:     100
  Concurrency:     2
  Max requests:    1000000
  Max duration:    5s
  Max RPS:         10
Latencies:
  0.5000: 1.335166ms
  0.9000: 3.4625ms
  0.9500: 8.540437ms
  0.9900: 24.980317ms
  0.9990: 34.061893ms
  0.9995: 34.566425ms
  1.0000: 35.070957ms
Elapsed time:      24.9s
Total requests:    50
RPS:               2.01

real    0m25.341s
user    0m0.328s
sys     0m0.107s

Expose TChannel ApplicationError

Currently we do not expose the TChannel "ApplicationError" bit. It's possible due to bugs that a server or relay returns the body of a Thrift exception, but does not set the application error bit correctly.

These issues will be much easier to debug if the application error is exposed on the response (similar to tcurl which returns an "ok" field)

When procedure is missing, list all available procedures

Currently we just return an error:

$ yab -p 127.0.0.1:5437 moe -t /usr/share/uber-idl/code.uber.internal/rt/moe/moe.thrift
Failed while parsing input: no procedure specified, specify --procedure [procedure]

Instead we should list all available procedures

request deadline is initialized too early

I noticed that when I specify a timeout of 2s, the actual header that is sent by Yab is Context-Ttl-Ms: 1999. This is because the code sets a "deadline" on the context object, and then uses that deadline for each request. Therefore any time that elapses between when the deadline is calculated and when Yab actually schedules the first request will be subtracted from the request time.

I think this is counter-intuitive. The deadline should be computed at the same time the first request is made, not before.

Should all HTTP headers be displayed in the output

When making HTTP requests, yab currently shows all response HTTP headers in the "headers" section. Should we be stripping common HTTP headers away (unless explicitly left on by a transport option), or should headers always be hidden?

Current output:

{
  "body": {
    "result": 5
  },
  "headers": {
    "Content-Length": "23",
    "Content-Type": "application/x-thrift",
    "Date": "Wed, 01 Jun 2016 15:55:10 GMT"
  }
}

problem parsing response with --encoding=json

$ yab --peer-list=hosts.json --service=autobahn --method=hosts_v1 --encoding=json --request='{"serviceName":"foo"}'
Failed while parsing response: failed to parse JSON: json: cannot unmarshal array into Go value of type map[string]interface {}

with tcurl the response is

$ tcurl -H hosts.json autobahn hosts_v1 -3 '{"serviceName":"foo"}' | jq .
{
  "ok": true,
  "head": null,
  "body": [...],
  "headers": {
    "as": "json"
  },
  "trace": "7075701ec1913375"
}

Ability to fan out to all peers and return results

When using -P, a single request will randomly select a peer, while benchmarking will round-robin between peers.

It would be nice to support some sort of a --fanout option to fanout a request to all peers. E.g.,

$ yab -p 1.1.1.1:1 -p 2.2.2.2:2 moe --health
1.1.1.1:1
[ health output]
2.2.2.2:2
[ health output ]

Benchmarking with --fanout should benchmark each individual host:port individually and return results so we can easily determine which instance is slower.

cc: @nomis52

Support -P with -p for HTTP URL templates.

A peer list is not sufficient for HTTP with TLS or an alternate path. We can use the -p flag as a template and punch addresses from the peer list into that template.

feature: -t/--thrift flag traverses directories

Feature request

If -t/--thrift is passed a directory, yab will traverse it to find an appropriate *.thrift definition file for the service being called.

Motivation

The primary motivator for this change is simplicity for end-users.

In ecosystems where users make adhoc yab calls across numerous microservices, it can be cumbersome to constantly specify a *.thrift file with the -t/--thrift flag. Users will be able to specify a root IDL directory (e.g. /usr/share/my-idls/), and yab will find the right definition file for the service being called.

Further, the -t/--thrift setting could be predefined in defaults.ini to reduce the need for supplying the flag altogether.

Discussion

Namespace collisions of service names could make it difficult to find the thrift file for the intended service being invoked. This shouldn't be a problem for most usage, but it's not immediately clear how to handle those edge cases.

Additionally, there is some non-trivial overhead to traversing a large set of thrift definition files. For a tool like yab, this is possibly undesirable, but users always have the option to explicitly list a file using the -t/--thrift flag if speed becomes a concern.

Pluggable peer chooser

Yab should accept an alternate peer chooser for use in conjunction with -P and benchmarks or --fanout, e.g., yab --peer-list peers --choose least-pending --fan-out.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.