Commit Graph

338 Commits

Author SHA1 Message Date
Carl Mastrangelo fdd062c465 core: make max message size part of the public API 2016-10-27 14:11:44 -07:00
Carl Mastrangelo 2417660687 netty: fix static data race on handler settings 2016-10-26 13:52:10 -07:00
Carl Mastrangelo 8702185e8c netty: use memory efficient slice in Buffer 2016-10-20 13:29:36 -07:00
Jakob Buchgraber 6fa63a6371 netty: Upgrade to 4.1.6 and tcnative Fork23. Fixes #2224 (#2349) 2016-10-20 00:24:58 +02:00
Jakob Buchgraber 10f4c90f4e core: Call onSentBytes only if future is successfull. (#2339)
For example, if opening a stream failed after a DATA frame had already been queued.
2016-10-17 19:23:19 +02:00
Jakob Buchgraber 1e1c71d74c netty: Add toString() to GrpcHttp2InboundHeaders. Fixes #2341. (#2342)
Binary header values are printed in their base64 encoded form.

The GrpcHttpOutboundHeaders, as mentioned in the issue, don't seem to be affected by this regression. The toString() method seems fine.
2016-10-14 18:57:08 +02:00
Jakob Buchgraber 96069958f6 netty: Remove RequestMessagesCommand (#2333)
It's not needed. Can do the same by scheduling a task on the eventloop.
2016-10-14 01:23:19 +02:00
Jakob Buchgraber 14cc0dbe2b netty: Special case Http2ChannelClosedException. Fixes #2279 (#2334) 2016-10-14 00:14:55 +02:00
Eric Anderson e7ce41dd94 all: Style, unused, and errorprone fixes 2016-10-12 16:57:01 -07:00
Kun Zhang 132f7a9a33 core: Census integration for stats (#2262)
Highlights
==========

StatsTraceContext
-----------------

The bridge between gRPC library and Census. It keeps track of the total
payload sizes and the elapsed time of a Call. The rest of the gRPC code
doesn't invoke Census directly.

Context propagation
-------------------

StatsTraceContext carries CensusContext (and the upcoming TraceContext)
and is attached to the gRPC Context.

1. StatsTraceContext is created by ManagedChannelImpl, by calling
createClientContext(), which inherits the current CensusContext if available.

2. ManagedChannelImpl passes StatsTraceContext to ClientCallImpl, then
to the stream, then to the framer and deframer explicitly.

3. ClientCallImpl propagates the CensusContext to the headers.

1. ServerImpl creates a StatsTraceContext by implementing a new callback
method StatsTraceContext methodDetermined(MethodDescriptor, Metadata) on
ServerTransportListener.

2. NettyServerHandler calls methodDetermined() before creating the
stream, and passes the StatsTraceContext to the stream.

3. When ServerImpl creates the gRPC Context for the new ServerCall, it
calls the new method statsTraceContext() on ServerStream and puts the
StatsTraceContext in the Context.

Metrics recording
-----------------

1. Client-side start time: when ClientCallImpl is created

2. Server-side start time: when methodDetermined() is called

3. Server-side end time: in ServerStreamListener.closed(), but before
calling onComplete() or onCancel() on ServerCall.Listener.

4. Client-side end time: in ClientStreamListener.closed(), but before
calling onClonse() on ClientCall.Listener

Message sizes are recorded in MessageFramer and MessageDeframer. Both
the uncompressed and wire (possibly compressed) payload sizes are
counted.

TODOs
=====

The CensusContext created from headers on the server side should be
attached to the gRPC Context for the call.  It's not done at this moment
because Census lacks the proper API to do it. It only affects tracing
and resource accounting, but doesn't affect stats functionality
2016-10-06 17:15:24 -07:00
dapengzhang0 4e5765a93f all: fix minor JavaStyle errors found in code sync 2016-10-05 09:28:16 -07:00
Eric Anderson cad7124c27 core,netty: split stream state on client-side; AbstractStream2
OkHttp will need to be migrated in a future commit.
2016-10-03 11:10:38 -07:00
Jakob Buchgraber 7aa0e1a901 netty: server support extension content types (#2306)
Removed a (left over?) content type check that checks for equality with "application/grpc".
The content type is verified using checkContentType(..).
2016-09-30 10:05:21 +02:00
Carl Mastrangelo 34812835a8 interop-testing: limit the amount of noise from failing tests
Also mark Netty class as internal
2016-09-28 17:09:39 -07:00
Carl Mastrangelo f5f9ca52c8 all: fix minor bugs discovered on import 2016-09-28 14:35:51 -07:00
Łukasz Strzałkowski ce78224e0b netty: Refactor passing down SSL Session (#2295)
Create generic interface for handling passing down arbitrary attributes from
protocol negotiation handlers.

Addresses #1556.
2016-09-23 19:04:53 -07:00
Carl Mastrangelo 141eed5ed0 core: change Metadata internals to avoid garbage creation
Before:
Benchmark                                                                   (headerCount)    Mode     Cnt        Score    Error  Units
InboundHeadersBenchmark.defaultHeaders_clientHandler                                  N/A    avgt      10      240.879 ±  4.903  ns/op
InboundHeadersBenchmark.defaultHeaders_serverHandler                                  N/A    avgt      10      882.354 ± 16.177  ns/op
InboundHeadersBenchmark.grpcHeaders_clientHandler                                     N/A    avgt      10      208.068 ±  5.380  ns/op
InboundHeadersBenchmark.grpcHeaders_serverHandler                                     N/A    avgt      10      477.604 ±  8.200  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                           1  sample  234233      125.232 ± 11.903  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                           5  sample  344367      264.343 ± 18.318  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                          10  sample  392273      439.640 ±  2.589  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                          20  sample  221506      855.115 ± 38.899  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                           1  sample  253676      111.941 ±  2.742  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                           5  sample  368499      248.255 ±  2.601  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                          10  sample  390015      439.651 ± 11.040  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                          20  sample  221807      840.435 ± 21.667  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                            1  sample  230139      432.866 ± 25.503  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                            5  sample  226901      765.095 ± 19.969  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                           10  sample  260495     1268.239 ± 21.850  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                           20  sample  311526     2059.973 ± 23.503  ns/op

After:

Benchmark                                                                   (headerCount)    Mode     Cnt        Score    Error  Units
InboundHeadersBenchmark.defaultHeaders_clientHandler                                  N/A    avgt      10      104.317 ±  1.973  ns/op
InboundHeadersBenchmark.defaultHeaders_serverHandler                                  N/A    avgt      10      395.666 ± 11.056  ns/op
InboundHeadersBenchmark.grpcHeaders_clientHandler                                     N/A    avgt      10       64.147 ±  4.076  ns/op
InboundHeadersBenchmark.grpcHeaders_serverHandler                                     N/A    avgt      10      228.299 ±  2.874  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                           1  sample  252451      102.718 ±  2.714  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                           5  sample  239976      225.812 ± 38.824  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                          10  sample  258119      364.475 ± 57.217  ns/op
OutboundHeadersBenchmark.convertClientHeaders                                          20  sample  260138      676.950 ± 36.243  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                           1  sample  276064      105.371 ±  1.859  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                           5  sample  255128      190.970 ± 16.475  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                          10  sample  272923      366.769 ± 28.204  ns/op
OutboundHeadersBenchmark.convertServerHeaders                                          20  sample  264797      641.961 ± 18.879  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                            1  sample  226078      425.262 ±  3.481  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                            5  sample  253606      675.488 ± 26.001  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                           10  sample  286556     1157.014 ± 12.923  ns/op
OutboundHeadersBenchmark.encodeClientHeaders                                           20  sample  345649     1874.806 ± 36.227  ns/op
2016-09-19 14:25:48 -07:00
Jakob Buchgraber af2434375a netty: complete promise when RequestMessagesCommand 2016-09-13 21:41:56 +02:00
Jakob Buchgraber 4aadf550ee netty: Fix receipt of ClosedChannelException instead of actual error. Fixes #1330.
Our API allows pings to be send even after the transport has been shutdown. We currently
don't handle the case, where the Netty channel has been closed but the NettyClientHandler
has not yet been removed from the pipeline, correctly. That is, we need to query the shutdown
status whenever we receive a ClosedChannelException.

Also, some cleanup.
2016-09-12 19:17:34 +02:00
Jakob Buchgraber 8c18a0d355 netty: use custom http2 headers for decoding.
The DefaultHttp2Headers class is a general-purpose Http2Headers implementation
and provides much more functionality than we need in gRPC. In gRPC, when reading
headers off the wire, we only inspect a handful of them, before converting to
Metadata.

This commit introduces a Http2Headers implementation that aims for insertion
efficiency, a low memory footprint and fast conversion to Metadata.

  - Header names and values are stored in plain byte[].
  - Insertion is O(1), while lookup is now O(n).
  - Binary header values are base64 decoded as they are inserted.
  - The byte[][] returned by namesAndValues() can directly be used to construct
    a new Metadata object.
  - For HTTP/2 request headers, the pseudo headers are no longer carried over to
    Metadata.

A microbenchmark aiming to replicate the usage of Http2Headers in NettyClientHandler
and NettyServerHandler shows decent throughput gains when compared to DefaultHttp2Headers.

Benchmark                                             Mode  Cnt     Score    Error  Units
InboundHeadersBenchmark.defaultHeaders_clientHandler  avgt   10   283.830 ±  4.063  ns/op
InboundHeadersBenchmark.defaultHeaders_serverHandler  avgt   10  1179.975 ± 21.810  ns/op
InboundHeadersBenchmark.grpcHeaders_clientHandler     avgt   10   190.108 ±  3.510  ns/op
InboundHeadersBenchmark.grpcHeaders_serverHandler     avgt   10   561.426 ±  9.079  ns/op

Additionally, the memory footprint is reduced by more than 50%!

gRPC Request Headers: 864 bytes
Netty Request Headers: 1728 bytes
gRPC Response Headers: 216 bytes
Netty Response Headers: 528 bytes

Furthermore, this change does most of the gRPC groundwork necessary to be able
to cache higher ordered objects in HPACK's dynamic table, as discussed in [1].

[1] https://github.com/grpc/grpc-java/issues/2217
2016-09-09 23:15:18 +02:00
Carl Mastrangelo 35c3f8171b core/internal: replace make Stream id a primitive 2016-09-08 17:39:51 -07:00
Carl Mastrangelo f78644d762 core: add Metadata.discardAll()
Metadata.removeAll creates an iterator for looking through removed
values even if the call doens't use it.  This change adds a similar
method which doesn't create garbage.

This change makes it easier in the future to alter the internals
of Metadata where it may be expensive to return removed values.
2016-09-08 10:29:22 -07:00
Carl Mastrangelo ca5a402fe6 netty: cache method path conversion
Benchmark                                      Mode      Cnt   Score   Error  Units
MethodDescriptorBenchmark.direct             sample  1179094  43.483 ± 0.610  ns/op
MethodDescriptorBenchmark.old                sample  1079285  66.210 ± 5.402  ns/op
MethodDescriptorBenchmark.transportSpecific  sample  1408070  36.800 ± 0.423  ns/op
2016-09-07 14:41:02 -07:00
Kun Zhang 58d78dd0aa core: add ServerTransportFilter
Called whenever a ServerTransport is ready and terminated.  Has the
ability to modify transport attributes, which ServerCall.attributes()
are based on.

Related changes:

- Attribute keys for remote address and SSL session are now moved from
ServerCall to a neutral place io.grpc.Grpc, because they can also be
used from ServerTransportFilter, and probably will be used on the
client-side too.  The old keys on ServerCall is marked deprecated and
are equivalent to the new keys.
- Added transportReady() to ServerTransportListener.

Resolves #2132
2016-08-31 14:45:15 -07:00
mfcripps 8a0c89a9f8 integration-tests: add integration tests for auto window sizing 2016-08-19 15:55:39 -07:00
mfcripps 9ef13a4725 netty: add window resizing to netty handlers and unit tests 2016-08-17 16:21:30 -07:00
Carl Mastrangelo 1285477133 all: add parameter name to checkNotNull
After debugging #2153, it would have been nice to know what the exact
parameter was that was null. This change adds a name for each
checkNotNull (and tries to normalized on static imports in order to
shorten lines)
2016-08-12 14:55:00 -07:00
Eric Anderson 7d464fcb02 inprocess: Avoid creating unnecessary threads
Implementations of ManagedClientTransport.start() are restricted from
calling the passed listener until start() returns, in order to avoid
reentrency problems with locks. For most transports this isn't a
problem, because they need additional threads anyway. InProcess uses no
additional threads naturally so ends up needing a thread just to
notifyReady. Now transports can just return a Runnable that can be run
after locks are dropped.

This was originally intended to be a performance optimization, but the
thread also causes nondeterminism because RPCs are delayed until
notifyReady is called. So avoiding the thread reduces needless fakes
during tests.
2016-08-02 13:16:36 -07:00
Eric Anderson e23d7ec08a netty: Add test for AbstractHttp2Headers
This increases line coverage by 1.3%.
2016-07-20 16:54:35 -07:00
Eric Anderson 4289aaf79c core: Hard-code a list of providers for Android
Class.getResource() is expensive on Android, which is used by
ServiceLoader. So we hard-code a list for Android instead.

Fixes #2037
2016-07-20 09:49:59 -07:00
Carl Mastrangelo 297af4425e netty: always flush at least once, even if there were no writes 2016-07-19 11:18:54 -07:00
Carl Mastrangelo 953599543e netty: reduce contention in WriteQueue
WriteQueue uses LinkedBlockingQueue, which has stronger synchronization
semantics than we need.  It also requires that we batch reads from it
in order to get reasonable performance.  After profiling the delay
between writing to LBQ and reading from it, there was a ~10us delay.

This change switches to using ConcurrentLinkedQueue as the underlying
queue, and removes the batching (reads).  Using CLQ with batching is
slightly slower.

Benchmarks show favorable numbers for both latency and throughput.
Each of the following results were run serveral times:

Before:
Benchmark                         (direct)  (transport)    Mode     Cnt       Score     Error  Units
TransportBenchmark.unaryCall1024      true        NETTY  sample  321575  124185.027 ± 406.112  ns/op
TransportBenchmark.unaryCall1024     false        NETTY  sample  237400  168232.991 ± 548.043  ns/op

After:
Benchmark                         (direct)  (transport)    Mode     Cnt       Score     Error  Units
TransportBenchmark.unaryCall1024      true        NETTY  sample  354773  112552.339 ± 362.471  ns/op
TransportBenchmark.unaryCall1024     false        NETTY  sample  263297  151660.490 ± 507.463  ns/op

Qps with 10 outstanding RPCs per channel:

Before:
Channels:                       4
Outstanding RPCs per Channel:   10
Server Payload Size:            0
Client Payload Size:            0
50%ile Latency (in micros):     396
90%ile Latency (in micros):     680
95%ile Latency (in micros):     838
99%ile Latency (in micros):     1476
99.9%ile Latency (in micros):   5231
Maximum Latency (in micros):    43327
QPS:                            85761

After:
Channels:                       4
Outstanding RPCs per Channel:   10
Server Payload Size:            0
Client Payload Size:            0
50%ile Latency (in micros):     384
90%ile Latency (in micros):     612
95%ile Latency (in micros):     725
99%ile Latency (in micros):     1080
99.9%ile Latency (in micros):   3107
Maximum Latency (in micros):    30447
QPS:                            93353

The results are even better when under heavy load.  Qps with 100
outstanding RPCs per channel:

Before:
Channels:                       4
Outstanding RPCs per Channel:   100
Server Payload Size:            0
Client Payload Size:            0
50%ile Latency (in micros):     2735
90%ile Latency (in micros):     5051
95%ile Latency (in micros):     6219
99%ile Latency (in micros):     9271
99.9%ile Latency (in micros):   13759
Maximum Latency (in micros):    44831
QPS:                            125775

After:
Channels:                       4
Outstanding RPCs per Channel:   100
Server Payload Size:            0
Client Payload Size:            0
50%ile Latency (in micros):     2697
90%ile Latency (in micros):     4639
95%ile Latency (in micros):     5539
99%ile Latency (in micros):     7931
99.9%ile Latency (in micros):   12335
Maximum Latency (in micros):    61823
QPS:                            131904
2016-07-18 09:50:47 -07:00
Jakob Buchgraber edf2c62fd5 netty: update to 4.1.2.Final and tcnative Fork18 2016-07-12 08:06:19 +02:00
Jakob Buchgraber 0d6a9de54c netty: deduplicate javadoc accidentially introduced in e80b136495 2016-07-10 09:51:16 +02:00
Jakob Buchgraber e80b136495 Fix wrong use of checkNotNull in WriteQueue.
* Fix wrong use of checkNotNull in WriteQueue.

The issue was found and reported by @blakearnold. Thank you!
2016-07-08 16:00:34 +02:00
Eric Anderson 16b096b571 Reduce default max message size to 4 MiB
Fixes #1676
2016-07-07 13:34:53 -07:00
Jakob Buchgraber 2d7347fbfc netty: undo commit 6a55e29 as netty's DefaultThreadFactory has been fixed 2016-07-02 13:23:41 +02:00
Jakob Buchgraber 1257f96a00 netty: reduce allocations in write queue.
- Merge all the command objects with QueuedCommand so to save one object allocation per write.
- Add unit tests
2016-07-02 12:17:54 +02:00
Carl Mastrangelo 2292cbfca0 netty: prevent race between transportCreated and transportShutdown 2016-07-01 15:57:47 -07:00
Jakob Buchgraber c5733742ce netty: fix incorrect usage of AsciString.
An AsciiString object may only use a subsection of its backing byte array. We need to test for this and return a copy of the subsection if necessary.
Big thanks to @normanmaurer for uncovering this issue: https://github.com/netty/netty/issues/5472
2016-06-30 16:28:45 +02:00
ZHANG Dapeng 8ed2dc8bec testware: fix flakes caused by pickUnusedPort
Resolves #1756

The thread-unsafe method `io.grpc.testing.TestUtils.pickUnusedPort` causes flakes (#1756) in windows. Need to avoid use of this method in test as in windows the tests are running in different jvms and concurrent calls of this method in multiple processes tend to return the same port number.

There are some usages of this method in benchmarks, so moved the method to `io.grpc.benchmarks.Utils` and the method will only be used in benchmarks and not in test.
2016-06-28 13:34:38 -07:00
Jakob Buchgraber fc5197fbf4 netty: detect when ALPN was not used. Fixes #522 2016-06-25 15:59:30 +02:00
Kun Zhang 38b950f4f9 core: add transportInUse() to transport listener.
A transport is "in use" iff number of streams > 0. In following changes
the channel will use this information when deciding whether it should
transit to the IDLE mode (#1276).
2016-06-15 13:40:44 -07:00
Kun Zhang 432cec7973 core: CallCredentials
Introduce CallCredentials as a first-class option to allow applications
to set per-call credentials into headers for outgoing RPCs. This will
supersede ClientAuthInterceptor. It has access to more
information (e.g., transport attributes, MethodDescriptor) and allow
results to be returned asynchronously, e.g., from a blocking I/O, which
was problemantic with ClientAuthInterceptor.
2016-06-09 17:46:15 -07:00
ZHANG Dapeng b88ea27b53 core/internal: add 3-arg newStream method to ClientTransport interface (#1898)
adding 
ClientStream newStream(MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions);
to ClientTransport interface

Created this PR first because both fail fast implementation and another change will be using this interface change
2016-06-06 19:43:15 -07:00
Eric Anderson c6fd94ca85 Implement shutdownNow
Fixes #448
2016-06-02 17:39:59 -07:00
Jakob Buchgraber c6c74799f4 netty: add toString() to GrpcHttp2Headers 2016-06-02 18:18:55 +02:00
Carl Mastrangelo 676bf4854f core: fix nags from linter 2016-06-01 13:58:07 -07:00
Carl Mastrangelo 02eb24b3bd core,netty,okhttp: move user agent removal closer to where it is set 2016-06-01 12:55:21 -07:00
Carl Mastrangelo fa22259e3a netty: use custom Http2Headers class for encoding Metadata
Before:
Benchmark                              (headerCount)    Mode     Cnt     Score    Error  Units
HeadersBenchmark.convertClientHeaders             10  sample  127008   631.214 ±  3.543  ns/op
HeadersBenchmark.convertClientHeaders             20  sample  142036  1125.874 ± 21.114  ns/op
HeadersBenchmark.convertClientHeaders             50  sample  117570  2678.635 ± 47.764  ns/op
HeadersBenchmark.convertClientHeaders            100  sample  115919  5427.720 ± 67.956  ns/op
HeadersBenchmark.convertServerHeaders             10  sample  133903   610.970 ±  3.094  ns/op
HeadersBenchmark.convertServerHeaders             20  sample  138155  1154.304 ±  4.595  ns/op
HeadersBenchmark.convertServerHeaders             50  sample  120078  2658.175 ± 38.679  ns/op
HeadersBenchmark.convertServerHeaders            100  sample  120509  5212.341 ± 49.062  ns/op

After:
Benchmark                              (headerCount)    Mode     Cnt     Score    Error  Units
HeadersBenchmark.convertClientHeaders             10  sample  102473   407.383 ±  2.693  ns/op
HeadersBenchmark.convertClientHeaders             20  sample  103205   791.241 ± 38.054  ns/op
HeadersBenchmark.convertClientHeaders             50  sample  173817  1840.311 ±  5.718  ns/op
HeadersBenchmark.convertClientHeaders            100  sample  169984  3690.753 ± 44.308  ns/op
HeadersBenchmark.convertServerHeaders             10  sample  103615   401.661 ±  2.922  ns/op
HeadersBenchmark.convertServerHeaders             20  sample   99060   823.453 ±  5.553  ns/op
HeadersBenchmark.convertServerHeaders             50  sample  171824  1846.788 ± 29.840  ns/op
HeadersBenchmark.convertServerHeaders            100  sample  171622  3670.354 ±  7.127  ns/op
2016-05-25 17:23:51 -07:00