Search in sources :

Example 1 with BucketConfigRefreshFailedEvent

use of com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent in project couchbase-jvm-clients by couchbase.

the class KeyValueBucketRefresher method filterEligibleNodes.

/**
 * Helper method to generate a stream of KV nodes that can be used to fetch a config.
 *
 * <p>To be more resilient to failures, this method (similar to 1.x) shifts the node
 * list on each invocation by one to make sure we hit all of them eventually.</p>
 *
 * @param name the bucket name.
 * @return a flux of nodes that have the KV service enabled.
 */
private Flux<NodeInfo> filterEligibleNodes(final String name) {
    return Flux.defer(() -> {
        BucketConfig config = provider.config().bucketConfig(name);
        if (config == null) {
            eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.NO_BUCKET_FOUND, Optional.empty()));
            return Flux.empty();
        }
        List<NodeInfo> nodes = new ArrayList<>(config.nodes());
        shiftNodeList(nodes);
        return Flux.fromIterable(nodes).filter(n -> n.services().containsKey(ServiceType.KV) || n.sslServices().containsKey(ServiceType.KV)).take(MAX_PARALLEL_FETCH);
    });
}
Also used : Disposable(reactor.core.Disposable) ArrayList(java.util.ArrayList) EventBus(com.couchbase.client.core.cnc.EventBus) ServiceType(com.couchbase.client.core.service.ServiceType) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) Map(java.util.Map) Stability(com.couchbase.client.core.annotation.Stability) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) BucketConfig(com.couchbase.client.core.config.BucketConfig) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) Reactor(com.couchbase.client.core.Reactor) UTF_8(java.nio.charset.StandardCharsets.UTF_8) NodeInfo(com.couchbase.client.core.config.NodeInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Mono(reactor.core.publisher.Mono) FailFastRetryStrategy(com.couchbase.client.core.retry.FailFastRetryStrategy) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Optional(java.util.Optional) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) CarrierBucketConfigRequest(com.couchbase.client.core.msg.kv.CarrierBucketConfigRequest) Core(com.couchbase.client.core.Core) NodeInfo(com.couchbase.client.core.config.NodeInfo) ArrayList(java.util.ArrayList) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) BucketConfig(com.couchbase.client.core.config.BucketConfig)

Example 2 with BucketConfigRefreshFailedEvent

use of com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent in project couchbase-jvm-clients by couchbase.

the class ClusterManagerBucketRefresher method registerStream.

/**
 * Registers the given bucket name with the http stream.
 *
 * <p>Note that this method deliberately subscribes "out of band" and not being flatMapped into the
 * {@link #register(String)} return value. The idea is that the flux config subscription keeps on going
 * forever until specifically unsubscribed through either {@link #deregister(String)} or {@link #shutdown()}.</p>
 *
 * @param ctx the core context to use.
 * @param name the name of the bucket.
 * @return once registered, returns the disposable so it can be later used to deregister.
 */
private Disposable registerStream(final CoreContext ctx, final String name) {
    return Mono.defer(() -> {
        BucketConfigStreamingRequest request = new BucketConfigStreamingRequest(ctx.environment().timeoutConfig().managementTimeout(), ctx, BestEffortRetryStrategy.INSTANCE, name, ctx.authenticator());
        core.send(request);
        return Reactor.wrap(request, request.response(), true);
    }).flux().flatMap(res -> {
        if (res.status().success()) {
            return res.configs().map(config -> new ProposedBucketConfigContext(name, config, res.address()));
        } else {
            eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.MANAGER, BucketConfigRefreshFailedEvent.Reason.INDIVIDUAL_REQUEST_FAILED, Optional.of(res)));
            // and retry the whole thing
            return Flux.error(new ConfigException());
        }
    }).doOnError(e -> eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.MANAGER, BucketConfigRefreshFailedEvent.Reason.STREAM_FAILED, Optional.of(e)))).doOnComplete(() -> {
        eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.MANAGER, BucketConfigRefreshFailedEvent.Reason.STREAM_CLOSED, Optional.empty()));
        // handled in the retryWhen below.
        throw new ConfigException();
    }).retryWhen(Retry.any().exponentialBackoff(Duration.ofMillis(32), Duration.ofMillis(4096)).toReactorRetry()).subscribe(provider::proposeBucketConfig);
}
Also used : Disposable(reactor.core.Disposable) Reactor(com.couchbase.client.core.Reactor) Retry(com.couchbase.client.core.retry.reactor.Retry) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) BestEffortRetryStrategy(com.couchbase.client.core.retry.BestEffortRetryStrategy) Mono(reactor.core.publisher.Mono) BucketConfigStreamingRequest(com.couchbase.client.core.msg.manager.BucketConfigStreamingRequest) Flux(reactor.core.publisher.Flux) EventBus(com.couchbase.client.core.cnc.EventBus) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) Map(java.util.Map) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) ConfigException(com.couchbase.client.core.error.ConfigException) Optional(java.util.Optional) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) Core(com.couchbase.client.core.Core) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) ConfigException(com.couchbase.client.core.error.ConfigException) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) BucketConfigStreamingRequest(com.couchbase.client.core.msg.manager.BucketConfigStreamingRequest)

Example 3 with BucketConfigRefreshFailedEvent

use of com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent in project couchbase-jvm-clients by couchbase.

the class KeyValueBucketRefresher method fetchConfigPerNode.

/**
 * Helper method to fetch a config per node provided.
 *
 * <p>Note that the bucket config request sent here has a fail fast strategy, so that if nodes are offline they
 * do not circle the system forever (given they have a specific node target). Since the refresher polls every
 * fixed interval anyways, fresh requests will flood the system eventually and there is no point in keeping
 * the old ones around.</p>
 *
 * <p>Also, the timeout is set to the poll interval since it does not make sense to keep them around any
 * longer.</p>
 *
 * @param name the bucket name.
 * @param nodes the flux of nodes that can be used to fetch a config.
 * @return returns configs for each node if found.
 */
private Flux<ProposedBucketConfigContext> fetchConfigPerNode(final String name, final Flux<NodeInfo> nodes) {
    return nodes.flatMap(nodeInfo -> {
        CoreContext ctx = core.context();
        CarrierBucketConfigRequest request = new CarrierBucketConfigRequest(configRequestTimeout, ctx, new CollectionIdentifier(name, Optional.empty(), Optional.empty()), FailFastRetryStrategy.INSTANCE, nodeInfo.identifier());
        core.send(request);
        return Reactor.wrap(request, request.response(), true).filter(response -> {
            if (!response.status().success()) {
                eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.INDIVIDUAL_REQUEST_FAILED, Optional.of(response)));
            }
            return response.status().success();
        }).map(response -> new ProposedBucketConfigContext(name, new String(response.content(), UTF_8), nodeInfo.hostname())).onErrorResume(t -> {
            eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.INDIVIDUAL_REQUEST_FAILED, Optional.of(t)));
            return Mono.empty();
        });
    });
}
Also used : Disposable(reactor.core.Disposable) ArrayList(java.util.ArrayList) EventBus(com.couchbase.client.core.cnc.EventBus) ServiceType(com.couchbase.client.core.service.ServiceType) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) Map(java.util.Map) Stability(com.couchbase.client.core.annotation.Stability) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) BucketConfig(com.couchbase.client.core.config.BucketConfig) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) Reactor(com.couchbase.client.core.Reactor) UTF_8(java.nio.charset.StandardCharsets.UTF_8) NodeInfo(com.couchbase.client.core.config.NodeInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Mono(reactor.core.publisher.Mono) FailFastRetryStrategy(com.couchbase.client.core.retry.FailFastRetryStrategy) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Optional(java.util.Optional) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) CarrierBucketConfigRequest(com.couchbase.client.core.msg.kv.CarrierBucketConfigRequest) Core(com.couchbase.client.core.Core) CoreContext(com.couchbase.client.core.CoreContext) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) CarrierBucketConfigRequest(com.couchbase.client.core.msg.kv.CarrierBucketConfigRequest) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier)

Aggregations

Core (com.couchbase.client.core.Core)3 CoreContext (com.couchbase.client.core.CoreContext)3 Reactor (com.couchbase.client.core.Reactor)3 EventBus (com.couchbase.client.core.cnc.EventBus)3 BucketConfigRefreshFailedEvent (com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent)3 ConfigurationProvider (com.couchbase.client.core.config.ConfigurationProvider)3 ProposedBucketConfigContext (com.couchbase.client.core.config.ProposedBucketConfigContext)3 Duration (java.time.Duration)3 Map (java.util.Map)3 Optional (java.util.Optional)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 Disposable (reactor.core.Disposable)3 Flux (reactor.core.publisher.Flux)3 Mono (reactor.core.publisher.Mono)3 Stability (com.couchbase.client.core.annotation.Stability)2 BucketConfig (com.couchbase.client.core.config.BucketConfig)2 NodeInfo (com.couchbase.client.core.config.NodeInfo)2 CollectionIdentifier (com.couchbase.client.core.io.CollectionIdentifier)2 CarrierBucketConfigRequest (com.couchbase.client.core.msg.kv.CarrierBucketConfigRequest)2 FailFastRetryStrategy (com.couchbase.client.core.retry.FailFastRetryStrategy)2