io.vitess.client.Context.java Source code

Java tutorial

Introduction

Here is the source code for io.vitess.client.Context.java

Source

/*
 * Copyright 2019 The Vitess 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.vitess.client;

import io.vitess.proto.Vtrpc.CallerID;

import org.joda.time.Duration;
import org.joda.time.Instant;

import javax.annotation.Nullable;

/**
 * Context is an immutable object that carries per-request info.
 *
 * <p>RPC frameworks like gRPC have their own Context implementations that
 * allow propagation of deadlines, cancellation, and end-user credentials across RPC boundaries
 * (between client and server). Since these framework-specific Context implementations are not
 * compatible with one another, we provide our own Context class that wraps common features.
 *
 * <p>In gRPC and other frameworks, the current Context is maintained in
 * thread-local storage, so it's implicitly available to any method that needs it. In this Vitess
 * client library, we pass Context as an explicit parameter to methods that need it. This allows us
 * to defer enforcement of the specified request constraints until the request reaches the
 * underlying framework-specific Vitess client implementation, at which point the native Context
 * class can be used.
 */
public class Context {

    private static final Context DEFAULT_CONTEXT = new Context();
    private Instant deadline;
    private CallerID callerId;

    private Context() {
    }

    private Context(Instant deadline, CallerID callerId) {
        this.deadline = deadline;
        this.callerId = callerId;
    }

    // getDefault returns an empty context.
    public static Context getDefault() {
        return DEFAULT_CONTEXT;
    }

    // withDeadline returns a derived context with the specified maximum deadline.
    public Context withDeadline(Instant deadline) {
        if (this.deadline != null && this.deadline.isBefore(deadline)) {
            // You can't make a derived context with a later deadline than the parent.
            return this;
        }
        return new Context(deadline, callerId);
    }

    /**
     * withDeadlineAfter returns a derived context with a maximum deadline specified relative to the
     * current time.
     */
    public Context withDeadlineAfter(Duration duration) {
        return withDeadline(Instant.now().plus(duration));
    }

    // withCallerId returns a derived context with the specified callerId.
    public Context withCallerId(CallerID callerId) {
        if (this.callerId != null && this.callerId.equals(callerId)) {
            // Nothing changed.
            return this;
        }
        return new Context(deadline, callerId);
    }

    @Nullable
    public Instant getDeadline() {
        return deadline;
    }

    @Nullable
    public Duration getTimeout() {
        if (deadline == null) {
            return null;
        }
        return new Duration(null, deadline);
    }

    @Nullable
    public CallerID getCallerId() {
        return callerId;
    }
}