Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions benchmarks/src/jmh/java/io/grpc/netty/MethodDescriptorBenchmark.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2016, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package io.grpc.netty;

import io.grpc.InternalKnownTransport;
import io.grpc.InternalMethodDescriptor;
import io.grpc.MethodDescriptor;
import io.netty.util.AsciiString;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

/**
* Benchmark for Method Descriptors.
*/
@State(Scope.Benchmark)
public class MethodDescriptorBenchmark {

private static final MethodDescriptor.Marshaller<Void> marshaller =
new MethodDescriptor.Marshaller<Void>() {
@Override
public InputStream stream(Void value) {
return new ByteArrayInputStream(new byte[]{});
}

@Override
public Void parse(InputStream stream) {
return null;
}
};

MethodDescriptor<Void, Void> method = MethodDescriptor.create(
MethodDescriptor.MethodType.UNARY, "Service/Method", marshaller, marshaller);

InternalMethodDescriptor imd = new InternalMethodDescriptor(InternalKnownTransport.NETTY);

byte[] directBytes = new AsciiString("/" + method.getFullMethodName()).toByteArray();

/** Foo bar. */
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public AsciiString old() {
return new AsciiString("/" + method.getFullMethodName());
}

/** Foo bar. */
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public AsciiString transportSpecific() {
AsciiString path;
if ((path = (AsciiString) imd.geRawMethodName(method)) != null) {
path = new AsciiString("/" + method.getFullMethodName());
imd.setRawMethodName(method, path);
}
return path;
}

/** Foo bar. */
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public AsciiString direct() {
return new AsciiString(directBytes, false);
}
}

42 changes: 42 additions & 0 deletions core/src/main/java/io/grpc/InternalKnownTransport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2016, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package io.grpc;

/**
* All known transports.
*/
@Internal
public enum InternalKnownTransport {
NETTY,
;
}

55 changes: 55 additions & 0 deletions core/src/main/java/io/grpc/InternalMethodDescriptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2016, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package io.grpc;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Accesses internal data. Do not use this.
*/
@Internal
public final class InternalMethodDescriptor {
private final InternalKnownTransport transport;

public InternalMethodDescriptor(InternalKnownTransport transport) {
// TODO(carl-mastrangelo): maybe restrict access to this.
this.transport = checkNotNull(transport, "transport");
}

public Object geRawMethodName(MethodDescriptor<?, ?> md) {
return md.getRawMethodName(transport);
}

public void setRawMethodName(MethodDescriptor<?, ?> md, Object o) {
md.setRawMethodName(transport, o);
}
}
21 changes: 17 additions & 4 deletions core/src/main/java/io/grpc/MethodDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.google.common.base.Preconditions;

import java.io.InputStream;
import java.util.concurrent.atomic.AtomicReferenceArray;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
Expand All @@ -55,6 +56,17 @@ public class MethodDescriptor<ReqT, RespT> {
private final Marshaller<RespT> responseMarshaller;
private final boolean idempotent;

private final AtomicReferenceArray<Object> rawMethodNames =
new AtomicReferenceArray<Object>(InternalKnownTransport.values().length);

final Object getRawMethodName(InternalKnownTransport t) {
return rawMethodNames.get(t.ordinal());
}

final void setRawMethodName(InternalKnownTransport t, Object o) {
rawMethodNames.lazySet(t.ordinal(), o);
}

/**
* The call type of a method.
*/
Expand Down Expand Up @@ -152,10 +164,11 @@ public static <RequestT, ResponseT> MethodDescriptor<RequestT, ResponseT> create
type, fullMethodName, requestMarshaller, responseMarshaller, false);
}

private MethodDescriptor(MethodType type, String fullMethodName,
Marshaller<ReqT> requestMarshaller,
Marshaller<RespT> responseMarshaller,
boolean idempotent) {
private MethodDescriptor(
MethodType type, String fullMethodName,
Marshaller<ReqT> requestMarshaller,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent is a bit weird here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! I'll fix it.

Marshaller<RespT> responseMarshaller,
boolean idempotent) {
this.type = Preconditions.checkNotNull(type, "type");
this.fullMethodName = Preconditions.checkNotNull(fullMethodName, "fullMethodName");
this.requestMarshaller = Preconditions.checkNotNull(requestMarshaller, "requestMarshaller");
Expand Down
12 changes: 11 additions & 1 deletion netty/src/main/java/io/grpc/netty/NettyClientStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import static com.google.common.base.Preconditions.checkState;
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;

import io.grpc.InternalKnownTransport;
import io.grpc.InternalMethodDescriptor;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.Status;
Expand All @@ -56,6 +58,10 @@
* Client stream for a Netty transport.
*/
abstract class NettyClientStream extends Http2ClientStream implements StreamIdHolder {

private static final InternalMethodDescriptor methodDescriptorAccessor =
new InternalMethodDescriptor(InternalKnownTransport.NETTY);

private final MethodDescriptor<?, ?> method;
/** {@code null} after start. */
private Metadata headers;
Expand Down Expand Up @@ -94,7 +100,11 @@ public void start(ClientStreamListener listener) {
super.start(listener);

// Convert the headers into Netty HTTP/2 headers.
AsciiString defaultPath = new AsciiString("/" + method.getFullMethodName());
AsciiString defaultPath = (AsciiString) methodDescriptorAccessor.geRawMethodName(method);
if (defaultPath == null) {
defaultPath = new AsciiString("/" + method.getFullMethodName());
methodDescriptorAccessor.setRawMethodName(method, defaultPath);
}
headers.removeAll(GrpcUtil.USER_AGENT_KEY);
Http2Headers http2Headers
= Utils.convertClientHeaders(headers, scheme, defaultPath, authority, userAgent);
Expand Down