Skip to content

Commit

Permalink
core: split Context into a separate grpc-context artifact.
Browse files Browse the repository at this point in the history
The Context API is not particularly gRPC-specific, and will be used by
Census as its context propagation mechanism.

Removed all dependencies to make it easy for other libraries to depend
on.
  • Loading branch information
zhangkun83 committed Sep 2, 2016
1 parent 58d78dd commit c4f7f5c
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 29 deletions.
1 change: 1 addition & 0 deletions all/build.gradle
Expand Up @@ -14,6 +14,7 @@ buildscript {
def subprojects = [
project(':grpc-auth'),
project(':grpc-core'),
project(':grpc-context'),
project(':grpc-netty'),
project(':grpc-okhttp'),
project(':grpc-protobuf'),
Expand Down
14 changes: 14 additions & 0 deletions context/build.gradle
@@ -0,0 +1,14 @@
plugins {
id "be.insaneprogramming.gradle.animalsniffer" version "1.4.0"
}

description = 'gRPC: Context'

dependencies {
testCompile project(':grpc-testing')
}

// Configure the animal sniffer plugin
animalsniffer {
signature = "org.codehaus.mojo.signature:java16:+@signature"
}
Expand Up @@ -31,9 +31,6 @@

package io.grpc;

import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
Expand All @@ -44,8 +41,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.Nullable;

/**
* A context propagation mechanism which can carry scoped-values across API boundaries and between
* threads. Examples of state propagated via context include:
Expand Down Expand Up @@ -275,8 +270,8 @@ public CancellableContext withDeadlineAfter(long duration, TimeUnit unit,
*/
public CancellableContext withDeadline(Deadline deadline,
ScheduledExecutorService scheduler) {
Preconditions.checkNotNull(deadline, "deadline");
Preconditions.checkNotNull(scheduler, "scheduler");
checkNotNull(deadline, "deadline");
checkNotNull(scheduler, "scheduler");
return new CancellableContext(this, deadline, scheduler);
}

Expand Down Expand Up @@ -349,7 +344,7 @@ public Context attach() {
* will still be bound.
*/
public void detach(Context toAttach) {
Preconditions.checkNotNull(toAttach, "toAttach");
checkNotNull(toAttach, "toAttach");
if (toAttach.attach() != this) {
// Log a severe message instead of throwing an exception as the context to attach is assumed
// to be the correct one and the unbalanced state represents a coding mistake in a lower
Expand Down Expand Up @@ -383,7 +378,6 @@ public boolean isCancelled() {
* <p>The cancellation cause is provided for informational purposes only and implementations
* should generally assume that it has already been handled and logged properly.
*/
@Nullable
public Throwable cancellationCause() {
if (parent == null || !cascadesCancellation) {
return null;
Expand All @@ -396,7 +390,6 @@ public Throwable cancellationCause() {
* A context may have an associated {@link Deadline} at which it will be automatically cancelled.
* @return A {@link io.grpc.Deadline} or {@code null} if no deadline is set.
*/
@Nullable
public Deadline getDeadline() {
return DEADLINE_KEY.get(this);
}
Expand All @@ -406,8 +399,8 @@ public Deadline getDeadline() {
*/
public void addListener(final CancellationListener cancellationListener,
final Executor executor) {
Preconditions.checkNotNull(cancellationListener, "cancellationListener");
Preconditions.checkNotNull(executor, "executor");
checkNotNull(cancellationListener, "cancellationListener");
checkNotNull(executor, "executor");
if (canBeCancelled) {
ExecutableListener executableListener =
new ExecutableListener(executor, cancellationListener);
Expand All @@ -420,7 +413,7 @@ public void addListener(final CancellationListener cancellationListener,
// we can cascade listener notification.
listeners = new ArrayList<ExecutableListener>();
listeners.add(executableListener);
parent.addListener(parentListener, MoreExecutors.directExecutor());
parent.addListener(parentListener, DirectExecutor.INSTANCE);
} else {
listeners.add(executableListener);
}
Expand Down Expand Up @@ -689,13 +682,13 @@ public boolean isCurrent() {
}

/**
* Cancel this context and optionally provide a cause for the cancellation. This
* will trigger notification of listeners.
* Cancel this context and optionally provide a cause (can be {@code null}) for the
* cancellation. This will trigger notification of listeners.
*
* @return {@code true} if this context cancelled the context and notified listeners,
* {@code false} if the context was already cancelled.
*/
public boolean cancel(@Nullable Throwable cause) {
public boolean cancel(Throwable cause) {
boolean triggeredCancel = false;
synchronized (this) {
if (!cancelled) {
Expand All @@ -721,7 +714,7 @@ public boolean cancel(@Nullable Throwable cause) {
* @param toAttach context to make current.
* @param cause of cancellation, can be {@code null}.
*/
public void detachAndCancel(Context toAttach, @Nullable Throwable cause) {
public void detachAndCancel(Context toAttach, Throwable cause) {
try {
detach(toAttach);
} finally {
Expand All @@ -745,7 +738,6 @@ public boolean isCancelled() {
return false;
}

@Nullable
@Override
public Throwable cancellationCause() {
if (isCancelled()) {
Expand Down Expand Up @@ -778,7 +770,7 @@ public static class Key<T> {
}

Key(String name, T defaultValue) {
this.name = Preconditions.checkNotNull(name, "name");
this.name = checkNotNull(name, "name");
this.defaultValue = defaultValue;
}

Expand Down Expand Up @@ -842,4 +834,25 @@ public void cancelled(Context context) {
}
}
}

private static <T> T checkNotNull(T reference, Object errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
}
return reference;
}

private enum DirectExecutor implements Executor {
INSTANCE;

@Override
public void execute(Runnable command) {
command.run();
}

@Override
public String toString() {
return "Context.DirectExecutor";
}
}
}
Expand Up @@ -31,9 +31,6 @@

package io.grpc;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
Expand All @@ -58,9 +55,9 @@ public static Deadline after(long duration, TimeUnit units) {
return after(duration, units, SYSTEM_TICKER);
}

@VisibleForTesting
// For testing
static Deadline after(long duration, TimeUnit units, Ticker ticker) {
Preconditions.checkNotNull(units, "units");
checkNotNull(units, "units");
return new Deadline(ticker, units.toNanos(duration), true);
}

Expand Down Expand Up @@ -146,8 +143,8 @@ public long timeRemaining(TimeUnit unit) {
* @return {@link ScheduledFuture} which can be used to cancel execution of the task
*/
public ScheduledFuture<?> runOnExpiration(Runnable task, ScheduledExecutorService scheduler) {
Preconditions.checkNotNull(task, "task");
Preconditions.checkNotNull(scheduler, "scheduler");
checkNotNull(task, "task");
checkNotNull(scheduler, "scheduler");
return scheduler.schedule(task, deadlineNanos - ticker.read(), TimeUnit.NANOSECONDS);
}

Expand Down Expand Up @@ -179,4 +176,11 @@ public long read() {
return System.nanoTime();
}
}

private static <T> T checkNotNull(T reference, Object errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
}
return reference;
}
}
File renamed without changes.
Expand Up @@ -265,7 +265,7 @@ public void toString_before() {
assertEquals("12000 ns from now", d.toString());
}

static class FakeTicker extends Deadline.Ticker {
private static class FakeTicker extends Deadline.Ticker {
private long time;

@Override
Expand Down
3 changes: 2 additions & 1 deletion core/build.gradle
Expand Up @@ -7,7 +7,8 @@ description = 'gRPC: Core'
dependencies {
compile libraries.guava,
libraries.errorprone,
libraries.jsr305
libraries.jsr305,
project(':grpc-context')
testCompile project(':grpc-testing')
}

Expand Down
23 changes: 22 additions & 1 deletion core/src/test/java/io/grpc/CallOptionsTest.java
Expand Up @@ -51,13 +51,14 @@
import org.junit.runners.JUnit4;

import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/** Unit tests for {@link CallOptions}. */
@RunWith(JUnit4.class)
public class CallOptionsTest {
private String sampleAuthority = "authority";
private String sampleCompressor = "compressor";
private Deadline.Ticker ticker = new DeadlineTest.FakeTicker();
private Deadline.Ticker ticker = new FakeTicker();
private Deadline sampleDeadline = Deadline.after(1, NANOSECONDS, ticker);
private Key<String> sampleKey = Attributes.Key.of("sample");
private Attributes sampleAffinity = Attributes.newBuilder().set(sampleKey, "blah").build();
Expand Down Expand Up @@ -233,4 +234,24 @@ private static boolean equal(CallOptions o1, CallOptions o2) {
&& Objects.equal(o1.getAffinity(), o2.getAffinity())
&& Objects.equal(o1.getCredentials(), o2.getCredentials());
}

private static class FakeTicker extends Deadline.Ticker {
private long time;

@Override
public long read() {
return time;
}

public void reset(long time) {
this.time = time;
}

public void increment(long period, TimeUnit unit) {
if (period < 0) {
throw new IllegalArgumentException();
}
this.time += unit.toNanos(period);
}
}
}
2 changes: 2 additions & 0 deletions settings.gradle
@@ -1,5 +1,6 @@
rootProject.name = "grpc"
include ":grpc-core"
include ":grpc-context"
include ":grpc-stub"
include ":grpc-auth"
include ":grpc-okhttp"
Expand All @@ -16,6 +17,7 @@ include ":grpc-services"
include ":grpc-thrift"

project(':grpc-core').projectDir = "$rootDir/core" as File
project(':grpc-context').projectDir = "$rootDir/context" as File
project(':grpc-stub').projectDir = "$rootDir/stub" as File
project(':grpc-auth').projectDir = "$rootDir/auth" as File
project(':grpc-okhttp').projectDir = "$rootDir/okhttp" as File
Expand Down

0 comments on commit c4f7f5c

Please sign in to comment.