perfmark: add a perf annotation package

This commit is contained in:
Carl Mastrangelo 2019-03-29 11:29:36 -07:00 committed by GitHub
parent 5f88bc42bf
commit d8b5d84ce7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 729 additions and 0 deletions

View File

@ -45,6 +45,9 @@ javadoc {
// We want io.grpc.Internal, but not io.grpc.Internal*
exclude 'io/grpc/Internal?*.java'
exclude 'io/grpc/internal/**'
// Disabled until kinda stable.
exclude 'io/grpc/perfmark/**'
}
animalsniffer {

View File

@ -0,0 +1,445 @@
/*
* Copyright 2019 The 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.
*/
package io.grpc.perfmark;
import com.google.errorprone.annotations.CompileTimeConstant;
import javax.annotation.concurrent.ThreadSafe;
/**
* PerfMark is a collection of stub methods for marking key points in the RPC lifecycle. This
* class is {@link io.grpc.Internal} and {@link io.grpc.ExperimentalApi}. Do not use this yet.
*/
@ThreadSafe
public final class PerfMark {
private PerfMark() {
throw new AssertionError("nope");
}
/**
* Start a Task with a Tag to identify it; a task represents some work that spans some time, and
* you are interested in both its start time and end time.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskStart(String)} or {@link PerfTag#create(String)}.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStart(PerfTag tag, @CompileTimeConstant String taskName) {}
/**
* Start a Task with a Tag to identify it; a task represents some work that spans some time, and
* you are interested in both its start time and end time.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskStart(String)} or {@link PerfTag#create(String)}.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStart(
long scopeId, String scopeName, PerfTag tag, @CompileTimeConstant String taskName) {}
/**
* Start a Task; a task represents some work that spans some time, and you are interested in both
* its start time and end time.
*
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStart(@CompileTimeConstant String taskName) {}
/**
* Start a Task; a task represents some work that spans some time, and you are interested in both
* its start time and end time.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStart(
long scopeId, String scopeName, @CompileTimeConstant String taskName) {}
/**
* Start a Task with a Tag to identify it and with a time threshold; a task represents some work
* that spans some time, and you are interested in both its start time and end time.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A Task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskStartWithMinPeriod(long, String)} or {@link PerfTag#create(String)}.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStartWithMinPeriod(
PerfTag tag, long minPeriodNanos, @CompileTimeConstant String taskName) {}
/**
* Start a Task with a Tag to identify it and with a time threshold; a task represents some work
* that spans some time, and you are interested in both its start time and end time.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A Task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskStartWithMinPeriod(long, String)} or {@link PerfTag#create(String)}.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStartWithMinPeriod(
long scopeId,
String scopeName,
PerfTag tag,
long minPeriodNanos,
@CompileTimeConstant String taskName) {}
/**
* Start a Task with time threshold. A task represents some work that spans some time, and you are
* interested in both its start time and end time.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStartWithMinPeriod(
long minPeriodNanos, @CompileTimeConstant String taskName) {}
/**
* Start a Task with time threshold. A task represents some work that spans some time, and you are
* interested in both its start time and end time.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static void taskStartWithMinPeriod(
long scopeId, String scopeName, long minPeriodNanos, @CompileTimeConstant String taskName) {}
/** End a Task. See {@link #taskStart(PerfTag, String)}. */
public static void taskEnd() {}
/**
* End a Task. See {@link #taskStart(PerfTag, String)}.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
*/
public static void taskEnd(long scopeId, String scopeName) {}
/**
* Start a Task with a Tag to identify it in a try-with-resource statement; a task represents some
* work that spans some time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #task(String)} or {@link PerfTag#create(String)}.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask task(PerfTag tag, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task with a Tag to identify it in a try-with-resource statement; a task represents some
* work that spans some time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #task(String)} or {@link PerfTag#create(String)}.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask task(
long scopeId, String scopeName, PerfTag tag, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task it in a try-with-resource statement; a task represents some work that spans some
* time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask task(@CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task it in a try-with-resource statement; a task represents some work that spans some
* time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask task(
long scopeId, String scopeName, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task with a Tag to identify it, and with time threshold, in a try-with-resource
* statement; a task represents some work that spans some time, and you are interested in both its
* start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskWithMinPeriod(long, String)} or {@link PerfTag#create(String)}.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask taskWithMinPeriod(
PerfTag tag, long minPeriodNanos, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task with a Tag to identify it, and with time threshold, in a try-with-resource
* statement; a task represents some work that spans some time, and you are interested in both its
* start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #taskWithMinPeriod(long, String)} or {@link PerfTag#create(String)}.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask taskWithMinPeriod(
long scopeId,
String scopeName,
PerfTag tag,
long minPeriodNanos,
@CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task with time threshold in a try-with-resource statement; a task represents some work
* that spans some time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask taskWithMinPeriod(
long minPeriodNanos, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
/**
* Start a Task with time threshold in a try-with-resource statement; a task represents some work
* that spans some time, and you are interested in both its start time and end time.
*
* <p>Use this in a try-with-resource statement so that task will end automatically.
*
* <p>Sometimes, you may be interested in only events that take more than a certain time
* threshold. In such cases, you can use this method. A task that takes less than the specified
* threshold, along with all its sub-tasks, events, and additional tags will be discarded.
*
* @param scopeId The scope of the task. The scope id is used to join task starting and ending
* across threads. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param minPeriodNanos Tasks that takes less than the specified time period, in nanosecond, will
* be discarded, along with its sub-tasks, events, and additional tags.
* @param taskName The name of the task. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this task.
*/
public static PerfMarkTask taskWithMinPeriod(
long scopeId, String scopeName, long minPeriodNanos, @CompileTimeConstant String taskName) {
return AUTO_DO_NOTHING;
}
static final PerfMarkTask AUTO_DO_NOTHING = new PerfMarkTask() {
@Override
public void close() {}
};
/**
* Records an Event with a Tag to identify it.
*
* <p>An Event is different from a Task in that you don't care how much time it spanned. You are
* interested in only the time it happened.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #event(String)} or {@link PerfTag#create(String)}.
* @param eventName The name of the event. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this event.
*/
public static void event(PerfTag tag, @CompileTimeConstant String eventName) {}
/**
* Records an Event with a Tag to identify it.
*
* <p>An Event is different from a Task in that you don't care how much time it spanned. You are
* interested in only the time it happened.
*
* @param scopeId The scope of the event. The scope id is used to associated the event with a
* particular scope. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* #event(String)} or {@link PerfTag#create(String)}.
* @param eventName The name of the event. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this event.
*/
public static void event(
long scopeId, String scopeName, PerfTag tag, @CompileTimeConstant String eventName) {}
/**
* Records an Event.
*
* <p>An Event is different from a Task in that you don't care how much time it spanned. You are
* interested in only the time it happened.
*
* @param eventName The name of the event. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this event.
*/
public static void event(@CompileTimeConstant String eventName) {}
/**
* Records an Event.
*
* <p>An Event is different from a Task in that you don't care how much time it spanned. You are
* interested in only the time it happened.
*
* @param scopeId The scope of the event. The scope id is used to associate the event with a
* particular scope. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param eventName The name of the event. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this event.
*/
public static void event(long scopeId, String scopeName, @CompileTimeConstant String eventName) {}
/**
* Add an additional tag to the last task that was started.
*
* <p>A tag is different from an Event or a task in that clients don't care about the time at
* which this tag is added. Instead, it allows clients to associate an additional tag to the
* current Task.
*
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* PerfTag#create(String)}.
* @param tagName The name of the tag. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this tag.
*/
public static void tag(PerfTag tag, @CompileTimeConstant String tagName) {}
/**
* Add an additional tag to the last task that was started.
*
* <p>A tag is different from an Event or a task in that clients don't care about the time at
* which this tag is added. Instead, it allows clients to associate an additional tag to the
* current Task.
*
* @param scopeId The scope of the tag. The scope id is used to associate a tag with a particular
* scope. The scope id must be a positive number.
* @param scopeName The name of the scope.
* @param tag a Tag object associated with the task. See {@link PerfTag} for description. Don't
* use 0 for the {@code numericTag} of the Tag object. 0 is reserved to represent that a task
* does not have a numeric tag associated. In this case, you are encouraged to use {@link
* PerfTag#create(String)}.
* @param tagName The name of the tag. <b>This parameter must be a compile-time constant!</b>
* Otherwise, instrumentation result will show "(invalid name)" for this tag.
*/
public static void tag(
long scopeId, String scopeName, PerfTag tag, @CompileTimeConstant String tagName) {}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2019 The 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.
*/
package io.grpc.perfmark;
import java.io.Closeable;
/**
* This class exists to make it easier for users to use the try-with-resource shorthand for
* starting and ending a PerfMark Task. This class is {@link io.grpc.Internal} and
* {@link io.grpc.ExperimentalApi}. Do not use this yet.
*/
public abstract class PerfMarkTask implements Closeable {
@Override
public abstract void close();
PerfMarkTask() {}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright 2019 The 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.
*/
package io.grpc.perfmark;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to add PerfMark instrumentation points surrounding method invocation.
*
* <p>This class is {@link io.grpc.Internal} and {@link io.grpc.ExperimentalApi}. Do not use this
* yet.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
// TODO(carl-mastrangelo): Add this line back in and make it okay on Android
//@IncompatibleModifiers(value = {Modifier.ABSTRACT, Modifier.NATIVE})
public @interface PerfMarker {
/**
* The name of the task; e.g. `parseHeaders`.
*/
String taskName();
/**
* An optional computed tag.
*
* <p>There are 3 supported references that can be used
* <ul>
* <li>{@code "this"}: Then the tag will be the {@link Object#toString} of the current class.
* Only valid for instance methods.
* <li>{@code "someFieldName"}: Then the tag will be the result of
* calling {@link String#valueOf(Object)} on the field. The field cannot be a primitive or
* and array type. (Though we may revisit this in the future).
* <li>{@code "$N"}: Then the tag will be the result of calling {@link String#valueOf(Object)}
* on the Nth method parameter. Parameters are {@code 0} indexed so {@code "$1"} is the
* second parameter. The referenced parameter cannot be a primitive or an array type.
* (Though we may revisit this in the future).
* </ul>
*
* <p>In general you should reference either {@code "this"} or {@code final} fields since
* in these cases we can cache the operations to decrease the cost of computing the tags. A side
* effect of this is that for such references we will not have their tags recalculated after the
* first time. Thus it is best to use immutable objects for tags.
*/
String computedTag() default "";
/**
* True if class with annotation is immutable and instrumentation must adhere to this restriction.
* If enableSampling is passed as argument to the agent, instrumentation points with <code>
* immutable = true </code> are ignored.
*/
boolean immutable() default false;
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 2019 The 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.
*/
package io.grpc.perfmark;
/**
* A Tag is used to provide additional information to identify a task and consists of a 64-bit
* integer value and a string.
*
* <p>Both the {@code numericTag} and the {@code stringTag} are optional. The {@code numericTag}
* value can be used to identify the specific task being worked on (e.g. the id of the rpc call).
* The {@code stringTag} can be used to store any value that is not a compile-time constant (a
* restriction imposed for the name passed to PerfMark tasks and events). A value of 0 for the
* {@code numericTag} is considered null. Don't use 0 for the {@code numericTag} unless you intend
* to specify null. In that case you are encouraged to use {@link #create(String)}.
*
* <p>Invocations to {@code create} methods in this class are a no-op unless PerfMark
* instrumentation is enabled. If so, calls to {@code create} methods to this class are replaced for
* calls to {@link TagFactory} create methods.
*
* <p>This class is {@link io.grpc.Internal} and {@link io.grpc.ExperimentalApi}. Do not use this
* yet.
*/
public final class PerfTag {
private static final long NULL_NUMERIC_TAG = 0;
private static final String NULL_STRING_TAG = "";
private static final PerfTag NULL_PERF_TAG = TagFactory.create(NULL_NUMERIC_TAG, NULL_STRING_TAG);
/**
* If PerfMark instrumentation is not enabled, returns a Tag with numericTag = 0L. Replacement
* for {@link TagFactory#create(long, String)} if PerfMark agent is enabled.
*/
public static PerfTag create(
@SuppressWarnings("unused") long numericTag, @SuppressWarnings("unused") String stringTag) {
// Warning suppression is safe as this method returns by default the NULL_TAG
return NULL_PERF_TAG;
}
/**
* If PerfMark instrumentation is not enabled returns a Tag with numericTag = 0L. Replacement
* for {@link TagFactory#create(String)} if PerfMark agent is enabled.
*/
public static PerfTag create(@SuppressWarnings("unused") String stringTag) {
// Warning suppression is safe as this method returns by default the NULL_TAG
return NULL_PERF_TAG;
}
/**
* If PerfMark instrumentation is not enabled returns a Tag with numericTag = 0L. Replacement
* for {@link TagFactory#create(long)} if PerfMark agent is enabled.
*/
public static PerfTag create(@SuppressWarnings("unused") long numericTag) {
// Warning suppression is safe as this method returns by default the NULL_TAG
return NULL_PERF_TAG;
}
/**
* Returns the null tag.
*/
public static PerfTag create() {
return NULL_PERF_TAG;
}
/**
* Allocates a unique, mostly sequential unique id for Tags. This method will be replaced with
* a call to a real implementation if instrumentation is enabled.
*/
public static final long allocateNumericId() {
return NULL_NUMERIC_TAG;
}
private final long numericTag;
private final String stringTag;
private PerfTag(long numericTag, String stringTag) {
this.numericTag = numericTag;
if (stringTag == null) {
throw new NullPointerException("stringTag");
}
this.stringTag = stringTag;
}
/** Returns the numeric tag if set, or {@link Constants#NULL_NUMERIC_TAG} instead. */
public long getNumericTag() {
return numericTag;
}
/** Returns the string tag if set, or {@link Constants#NULL_STRING_TAG} instead. */
public String getStringTag() {
return stringTag;
}
@Override
public String toString() {
return "Tag(numericTag=" + numericTag + ",stringTag='" + stringTag + "')";
}
@Override
public int hashCode() {
int longHashCode = (int)(numericTag ^ (numericTag >>> 32));
return longHashCode + (stringTag != null ? stringTag.hashCode() : 31);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PerfTag)) {
return false;
}
PerfTag other = (PerfTag) obj;
return this.numericTag == other.numericTag && this.stringTag.equals(other.stringTag);
}
/**
* Provides methods that create Tag instances which should not be directly invoked by clients.
*
* <p><b>Warning:</b> Clients should not call methods from this class directly because of the
* overhead involved in the creation of Tag objects when PerfMark instrumentation is not
* enabled.
*
* <p>Calls to {@link PerfTag#create(long)}, {@link PerfTag#create(long, String)} and {@link
* PerfTag#create(String)} are replaced with calls to the methods in this class using bytecode
* rewriting, if enabled.
*/
static final class TagFactory {
/**
* This class should not be instantiated.
*/
private TagFactory() {}
public static PerfTag create(long numericTag, String stringTag) {
return new PerfTag(numericTag, stringTag);
}
public static PerfTag create(String stringTag) {
return new PerfTag(NULL_NUMERIC_TAG, stringTag);
}
public static PerfTag create(long numericTag) {
return new PerfTag(numericTag, NULL_STRING_TAG);
}
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2019 The 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.
*/
/**
* This is an internal, experimental API and not subject to the normal compatibility guarantees.
*/
@io.grpc.Internal
package io.grpc.perfmark;