Search in sources :

Example 6 with Code

use of io.grpc.Status.Code in project etcd-java by IBM.

the class EtcdClient method refreshCredentials.

private CallCredentials refreshCredentials() {
    return new CallCredentials() {

        // TODO volatile TBD
        private Metadata tokenHeader;

        private final long authTime = System.currentTimeMillis();

        private final ListenableFuture<Metadata> futureTokenHeader = Futures.transform(authenticate(), (Function<AuthenticateResponse, Metadata>) ar -> tokenHeader = tokenHeader(ar));

        @Override
        public void applyRequestMetadata(MethodDescriptor<?, ?> method, Attributes attrs, Executor appExecutor, MetadataApplier applier) {
            Metadata tokHeader = tokenHeader;
            if (tokHeader != null)
                applier.apply(tokHeader);
            else
                futureTokenHeader.addListener(() -> {
                    try {
                        applier.apply(futureTokenHeader.get());
                    } catch (ExecutionException | InterruptedException ee) {
                        // (IE won't be thrown)
                        Status failStatus = Status.fromThrowable(ee.getCause());
                        Code code = failStatus != null ? failStatus.getCode() : null;
                        if (code != Code.INVALID_ARGUMENT && (System.currentTimeMillis() - authTime) > 15_000L) {
                            // this will force another auth attempt
                            failStatus = Status.UNAUTHENTICATED.withDescription("re-attempt re-auth");
                        }
                        applier.fail(failStatus);
                    }
                }, directExecutor());
        }

        // @Override
        public void thisUsesUnstableApi() {
        }
    };
}
Also used : Status(io.grpc.Status) Function(com.google.common.base.Function) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) MoreExecutors.directExecutor(com.google.common.util.concurrent.MoreExecutors.directExecutor) Executor(java.util.concurrent.Executor) Metadata(io.grpc.Metadata) Attributes(io.grpc.Attributes) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) MethodDescriptor(io.grpc.MethodDescriptor) Code(io.grpc.Status.Code) CallCredentials(io.grpc.CallCredentials)

Example 7 with Code

use of io.grpc.Status.Code in project etcd-java by IBM.

the class RangeCache method strongIterator.

/**
 * Iterator whose contents is guaranteed to be sequentially consistent
 * with remote updates to the cached range.
 *
 * @return an {@link Iterator} over the {@link KeyValues} of this cache
 */
public Iterator<KeyValue> strongIterator() {
    // memory barrier prior to reading seenUpToRev
    entries.get(fromKey);
    long seenUpTo = seenUpToRev;
    if (seenUpTo == 0L) {
        ListenableFuture<Boolean> startFut;
        synchronized (this) {
            startFut = startFuture;
        }
        if (startFut == null) {
            // cache has not yet been started
            return kvClient.get(fromKey).rangeEnd(toKey).timeout(120_000L).sync().getKvsList().iterator();
        } else
            try {
                startFut.get(2L, TimeUnit.MINUTES);
                // now started
                seenUpTo = seenUpToRev;
            } catch (TimeoutException te) {
                throw Status.DEADLINE_EXCEEDED.asRuntimeException();
            } catch (ExecutionException e) {
                throw Status.UNKNOWN.withCause(e).asRuntimeException();
            } catch (InterruptedException | CancellationException e) {
                throw Status.CANCELLED.withCause(e).asRuntimeException();
            }
    }
    /* 
         * This logic is similar to that in fullRefreshCache(), but
         * it includes an optimistic initial comparison of counts
         * to identify cases where no deletions have been missed and
         * thus a retrieval of all the keys isn't required.
         */
    RangeRequest.Builder rangeReqBld = RangeRequest.newBuilder().setKey(fromKey).setRangeEnd(toKey);
    RangeRequest curCountReq = rangeReqBld.setCountOnly(true).setMaxCreateRevision(seenUpTo).build();
    RangeRequest seenCountReq = rangeReqBld.clearMaxCreateRevision().setRevision(seenUpTo).build();
    RangeRequest newModsReq = rangeReqBld.clearRevision().clearCountOnly().setMinModRevision(seenUpTo + 1).build();
    // first, attempt to get:
    // 0- kvs modified since seenUpTo
    // 1- current count excluding those created since seenUpTo
    // 2- count at revision seenUpTo (this could potentially
    // fail with compaction error, see below)
    ListenableFuture<TxnResponse> txn = kvClient.batch().get(newModsReq).get(curCountReq).get(seenCountReq).async();
    TxnResponse txnResp;
    try {
        txnResp = waitFor(txn, 8000L);
    } catch (RuntimeException e) {
        Code code = Status.fromThrowable(e).getCode();
        if (code != Code.OUT_OF_RANGE)
            throw e;
        // if (2) above fails due to compaction, also retrieve all current keys
        RangeRequest otherKeysReq = rangeReqBld.clearMinModRevision().setMaxModRevision(seenUpTo).setKeysOnly(true).build();
        txnResp = waitFor(kvClient.batch().get(newModsReq).get(otherKeysReq).async(), // longer timeout
        60_000L);
    }
    long revNow = txnResp.getHeader().getRevision();
    if (revNow > seenUpToRev) {
        RangeResponse newModKvs = txnResp.getResponses(0).getResponseRange();
        List<KeyValue> otherKeys;
        if (txnResp.getResponsesCount() == 2) {
            // this means we must have taken the compacted exception path above
            otherKeys = txnResp.getResponses(1).getResponseRange().getKvsList();
        } else if (// <- latest count
        txnResp.getResponses(1).getResponseRange().getCount() < txnResp.getResponses(2).getResponseRange().getCount()) {
            // <- count at seenUpTo
            // if counts don't match, there must have been deletions since seenUpTo,
            // so additionally retrieve all current keys
            RangeRequest otherKeysReq = rangeReqBld.clearMinModRevision().setMaxModRevision(seenUpTo).setKeysOnly(true).build();
            // longer timeout
            otherKeys = waitFor(kvClient.get(otherKeysReq), 60_000L).getKvsList();
        } else
            otherKeys = null;
        boolean newKvs = newModKvs.getKvsCount() > 0;
        if (otherKeys != null) {
            // if this is true, there *might* be deletions to process
            if (otherKeys.isEmpty() && !newKvs)
                return Collections.emptyIterator();
            // bring cache up to date with recently deleted kvs
            Set<ByteString> keys = Stream.concat(otherKeys.stream(), newModKvs.getKvsList().stream()).map(kv -> kv.getKey()).collect(Collectors.toSet());
            entries.values().stream().filter(kv -> kv.getModRevision() < revNow && !keys.contains(kv.getKey())).forEach(kv -> offerDelete(kv.getKey(), revNow));
        }
        // bring cache up to date with recently modified kvs
        if (newKvs)
            newModKvs.getKvsList().forEach(kv -> offerUpdate(kv, false));
        if (revNow > seenUpToRev)
            listenerExecutor.execute(() -> revisionUpdate(revNow));
    }
    return iterator();
}
Also used : EtcdClient(com.ibm.etcd.client.EtcdClient) CompareResult(com.ibm.etcd.api.Compare.CompareResult) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) RevisionCompactedException(com.ibm.etcd.client.watch.RevisionCompactedException) StreamObserver(io.grpc.stub.StreamObserver) Compare(com.ibm.etcd.api.Compare) Map(java.util.Map) Status(io.grpc.Status) RangeResponse(com.ibm.etcd.api.RangeResponse) Function(com.google.common.base.Function) CancellationException(java.util.concurrent.CancellationException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) EventType(com.ibm.etcd.client.utils.RangeCache.Listener.EventType) Set(java.util.Set) NavigableSet(java.util.NavigableSet) NavigableMap(java.util.NavigableMap) GuardedBy(javax.annotation.concurrent.GuardedBy) Collectors(java.util.stream.Collectors) RequestOp(com.ibm.etcd.api.RequestOp) ByteString(com.google.protobuf.ByteString) CompareOrBuilder(com.ibm.etcd.api.CompareOrBuilder) List(java.util.List) Stream(java.util.stream.Stream) GrpcClient.waitFor(com.ibm.etcd.client.GrpcClient.waitFor) DeleteRangeResponse(com.ibm.etcd.api.DeleteRangeResponse) RangeRequest(com.ibm.etcd.api.RangeRequest) Event(com.ibm.etcd.api.Event) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MoreExecutors(com.google.common.util.concurrent.MoreExecutors) WatchUpdate(com.ibm.etcd.client.kv.WatchUpdate) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Watch(com.ibm.etcd.client.kv.KvClient.Watch) TxnResponse(com.ibm.etcd.api.TxnResponse) Iterators(com.google.common.collect.Iterators) ConcurrentMap(java.util.concurrent.ConcurrentMap) HashSet(java.util.HashSet) DeleteRangeRequest(com.ibm.etcd.api.DeleteRangeRequest) Code(io.grpc.Status.Code) KeyUtils(com.ibm.etcd.client.KeyUtils) PutRequest(com.ibm.etcd.api.PutRequest) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Executor(java.util.concurrent.Executor) KvClient(com.ibm.etcd.client.kv.KvClient) SerializingExecutor(com.ibm.etcd.client.SerializingExecutor) KeyValue(com.ibm.etcd.api.KeyValue) TxnRequest(com.ibm.etcd.api.TxnRequest) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Futures(com.google.common.util.concurrent.Futures) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) Collections(java.util.Collections) CompareTarget(com.ibm.etcd.api.Compare.CompareTarget) KeyValue(com.ibm.etcd.api.KeyValue) ByteString(com.google.protobuf.ByteString) Code(io.grpc.Status.Code) RangeResponse(com.ibm.etcd.api.RangeResponse) DeleteRangeResponse(com.ibm.etcd.api.DeleteRangeResponse) RangeRequest(com.ibm.etcd.api.RangeRequest) DeleteRangeRequest(com.ibm.etcd.api.DeleteRangeRequest) TxnResponse(com.ibm.etcd.api.TxnResponse) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

Code (io.grpc.Status.Code)7 Status (io.grpc.Status)3 Function (com.google.common.base.Function)2 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)2 Executor (java.util.concurrent.Executor)2 Test (org.junit.Test)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterators (com.google.common.collect.Iterators)1 Futures (com.google.common.util.concurrent.Futures)1 MoreExecutors (com.google.common.util.concurrent.MoreExecutors)1 MoreExecutors.directExecutor (com.google.common.util.concurrent.MoreExecutors.directExecutor)1 ByteString (com.google.protobuf.ByteString)1 Duration (com.google.protobuf.Duration)1 Compare (com.ibm.etcd.api.Compare)1 CompareResult (com.ibm.etcd.api.Compare.CompareResult)1 CompareTarget (com.ibm.etcd.api.Compare.CompareTarget)1 CompareOrBuilder (com.ibm.etcd.api.CompareOrBuilder)1 DeleteRangeRequest (com.ibm.etcd.api.DeleteRangeRequest)1