Search in sources :

Example 1 with BundleSplitOption

use of org.apache.pulsar.common.naming.BundleSplitOption in project pulsar by apache.

the class NamespaceService method splitAndOwnBundleOnceAndRetry.

void splitAndOwnBundleOnceAndRetry(NamespaceBundle bundle, boolean unload, AtomicInteger counter, CompletableFuture<Void> completionFuture, NamespaceBundleSplitAlgorithm splitAlgorithm, List<Long> boundaries) {
    BundleSplitOption bundleSplitOption = new BundleSplitOption(this, bundle, boundaries);
    splitAlgorithm.getSplitBoundary(bundleSplitOption).whenComplete((splitBoundaries, ex) -> {
        CompletableFuture<List<NamespaceBundle>> updateFuture = new CompletableFuture<>();
        if (ex == null) {
            if (splitBoundaries == null || splitBoundaries.size() == 0) {
                LOG.info("[{}] No valid boundary found in {} to split bundle {}", bundle.getNamespaceObject().toString(), boundaries, bundle.getBundleRange());
                completionFuture.complete(null);
                return;
            }
            try {
                bundleFactory.splitBundles(bundle, splitBoundaries.size() + 1, splitBoundaries).thenAccept(splittedBundles -> {
                    // Zookeeper.
                    if (splittedBundles == null) {
                        String msg = format("bundle %s not found under namespace", bundle.toString());
                        LOG.warn(msg);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
                        return;
                    }
                    checkNotNull(splittedBundles.getLeft());
                    checkNotNull(splittedBundles.getRight());
                    checkArgument(splittedBundles.getRight().size() == splitBoundaries.size() + 1, "bundle has to be split in " + (splitBoundaries.size() + 1) + " bundles");
                    NamespaceName nsname = bundle.getNamespaceObject();
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("[{}] splitAndOwnBundleOnce: {}, counter: {}, bundles: {}", nsname.toString(), bundle.getBundleRange(), counter.get(), splittedBundles.getRight());
                    }
                    try {
                        // take ownership of newly split bundles
                        for (NamespaceBundle sBundle : splittedBundles.getRight()) {
                            checkNotNull(ownershipCache.tryAcquiringOwnership(sBundle));
                        }
                        updateNamespaceBundles(nsname, splittedBundles.getLeft()).thenRun(() -> {
                            bundleFactory.invalidateBundleCache(bundle.getNamespaceObject());
                            updateFuture.complete(splittedBundles.getRight());
                        }).exceptionally(ex1 -> {
                            String msg = format("failed to update namespace policies [%s], " + "NamespaceBundle: %s due to %s", nsname.toString(), bundle.getBundleRange(), ex1.getMessage());
                            LOG.warn(msg);
                            updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, ex1.getCause()));
                            return null;
                        });
                    } catch (Exception e) {
                        String msg = format("failed to acquire ownership of split bundle for namespace [%s], %s", nsname.toString(), e.getMessage());
                        LOG.warn(msg, e);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, e));
                    }
                });
            } catch (Exception e) {
                updateFuture.completeExceptionally(e);
            }
        } else {
            updateFuture.completeExceptionally(ex);
        }
        // If success updateNamespaceBundles, then do invalidateBundleCache and unload.
        // Else retry splitAndOwnBundleOnceAndRetry.
        updateFuture.whenCompleteAsync((r, t) -> {
            if (t != null) {
                // retry several times on BadVersion
                if ((t.getCause() instanceof MetadataStoreException.BadVersionException) && (counter.decrementAndGet() >= 0)) {
                    pulsar.getOrderedExecutor().execute(() -> splitAndOwnBundleOnceAndRetry(bundle, unload, counter, completionFuture, splitAlgorithm, boundaries));
                } else if (t instanceof IllegalArgumentException) {
                    completionFuture.completeExceptionally(t);
                } else {
                    // Retry enough, or meet other exception
                    String msg2 = format(" %s not success update nsBundles, counter %d, reason %s", bundle.toString(), counter.get(), t.getMessage());
                    LOG.warn(msg2);
                    completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg2));
                }
                return;
            }
            // success updateNamespaceBundles
            // disable old bundle in memory
            getOwnershipCache().updateBundleState(bundle, false).thenRun(() -> {
                // update bundled_topic cache for load-report-generation
                pulsar.getBrokerService().refreshTopicToStatsMaps(bundle);
                loadManager.get().setLoadReportForceUpdateFlag();
                // release old bundle from ownership cache
                pulsar.getNamespaceService().getOwnershipCache().removeOwnership(bundle);
                completionFuture.complete(null);
                if (unload) {
                    // Unload new split bundles, in background. This will not
                    // affect the split operation which is already safely completed
                    r.forEach(this::unloadNamespaceBundle);
                }
            }).exceptionally(e -> {
                String msg1 = format("failed to disable bundle %s under namespace [%s] with error %s", bundle.getNamespaceObject().toString(), bundle.toString(), ex.getMessage());
                LOG.warn(msg1, e);
                completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg1));
                return null;
            });
        }, pulsar.getOrderedExecutor());
    });
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) CompletableFuture(java.util.concurrent.CompletableFuture) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) BundleSplitOption(org.apache.pulsar.common.naming.BundleSplitOption) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException)

Example 2 with BundleSplitOption

use of org.apache.pulsar.common.naming.BundleSplitOption in project incubator-pulsar by apache.

the class NamespaceService method splitAndOwnBundleOnceAndRetry.

void splitAndOwnBundleOnceAndRetry(NamespaceBundle bundle, boolean unload, AtomicInteger counter, CompletableFuture<Void> completionFuture, NamespaceBundleSplitAlgorithm splitAlgorithm, List<Long> boundaries) {
    BundleSplitOption bundleSplitOption = new BundleSplitOption(this, bundle, boundaries);
    splitAlgorithm.getSplitBoundary(bundleSplitOption).whenComplete((splitBoundaries, ex) -> {
        CompletableFuture<List<NamespaceBundle>> updateFuture = new CompletableFuture<>();
        if (ex == null) {
            if (splitBoundaries == null || splitBoundaries.size() == 0) {
                LOG.info("[{}] No valid boundary found in {} to split bundle {}", bundle.getNamespaceObject().toString(), boundaries, bundle.getBundleRange());
                completionFuture.complete(null);
                return;
            }
            try {
                bundleFactory.splitBundles(bundle, splitBoundaries.size() + 1, splitBoundaries).thenAccept(splittedBundles -> {
                    // Zookeeper.
                    if (splittedBundles == null) {
                        String msg = format("bundle %s not found under namespace", bundle.toString());
                        LOG.warn(msg);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
                        return;
                    }
                    checkNotNull(splittedBundles.getLeft());
                    checkNotNull(splittedBundles.getRight());
                    checkArgument(splittedBundles.getRight().size() == splitBoundaries.size() + 1, "bundle has to be split in " + (splitBoundaries.size() + 1) + " bundles");
                    NamespaceName nsname = bundle.getNamespaceObject();
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("[{}] splitAndOwnBundleOnce: {}, counter: {}, bundles: {}", nsname.toString(), bundle.getBundleRange(), counter.get(), splittedBundles.getRight());
                    }
                    try {
                        // take ownership of newly split bundles
                        for (NamespaceBundle sBundle : splittedBundles.getRight()) {
                            checkNotNull(ownershipCache.tryAcquiringOwnership(sBundle));
                        }
                        updateNamespaceBundles(nsname, splittedBundles.getLeft()).thenRun(() -> {
                            bundleFactory.invalidateBundleCache(bundle.getNamespaceObject());
                            updateFuture.complete(splittedBundles.getRight());
                        }).exceptionally(ex1 -> {
                            String msg = format("failed to update namespace policies [%s], " + "NamespaceBundle: %s due to %s", nsname.toString(), bundle.getBundleRange(), ex1.getMessage());
                            LOG.warn(msg);
                            updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, ex1.getCause()));
                            return null;
                        });
                    } catch (Exception e) {
                        String msg = format("failed to acquire ownership of split bundle for namespace [%s], %s", nsname.toString(), e.getMessage());
                        LOG.warn(msg, e);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, e));
                    }
                });
            } catch (Exception e) {
                updateFuture.completeExceptionally(e);
            }
        } else {
            updateFuture.completeExceptionally(ex);
        }
        // If success updateNamespaceBundles, then do invalidateBundleCache and unload.
        // Else retry splitAndOwnBundleOnceAndRetry.
        updateFuture.whenCompleteAsync((r, t) -> {
            if (t != null) {
                // retry several times on BadVersion
                if ((t.getCause() instanceof MetadataStoreException.BadVersionException) && (counter.decrementAndGet() >= 0)) {
                    pulsar.getOrderedExecutor().execute(() -> splitAndOwnBundleOnceAndRetry(bundle, unload, counter, completionFuture, splitAlgorithm, boundaries));
                } else if (t instanceof IllegalArgumentException) {
                    completionFuture.completeExceptionally(t);
                } else {
                    // Retry enough, or meet other exception
                    String msg2 = format(" %s not success update nsBundles, counter %d, reason %s", bundle.toString(), counter.get(), t.getMessage());
                    LOG.warn(msg2);
                    completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg2));
                }
                return;
            }
            // success updateNamespaceBundles
            // disable old bundle in memory
            getOwnershipCache().updateBundleState(bundle, false).thenRun(() -> {
                // update bundled_topic cache for load-report-generation
                pulsar.getBrokerService().refreshTopicToStatsMaps(bundle);
                loadManager.get().setLoadReportForceUpdateFlag();
                // release old bundle from ownership cache
                pulsar.getNamespaceService().getOwnershipCache().removeOwnership(bundle);
                completionFuture.complete(null);
                if (unload) {
                    // Unload new split bundles, in background. This will not
                    // affect the split operation which is already safely completed
                    r.forEach(this::unloadNamespaceBundle);
                }
            }).exceptionally(e -> {
                String msg1 = format("failed to disable bundle %s under namespace [%s] with error %s", bundle.getNamespaceObject().toString(), bundle.toString(), ex.getMessage());
                LOG.warn(msg1, e);
                completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg1));
                return null;
            });
        }, pulsar.getOrderedExecutor());
    });
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) CompletableFuture(java.util.concurrent.CompletableFuture) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) BundleSplitOption(org.apache.pulsar.common.naming.BundleSplitOption) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException)

Example 3 with BundleSplitOption

use of org.apache.pulsar.common.naming.BundleSplitOption in project pulsar by yahoo.

the class NamespaceService method splitAndOwnBundleOnceAndRetry.

void splitAndOwnBundleOnceAndRetry(NamespaceBundle bundle, boolean unload, AtomicInteger counter, CompletableFuture<Void> completionFuture, NamespaceBundleSplitAlgorithm splitAlgorithm, List<Long> boundaries) {
    BundleSplitOption bundleSplitOption = new BundleSplitOption(this, bundle, boundaries);
    splitAlgorithm.getSplitBoundary(bundleSplitOption).whenComplete((splitBoundaries, ex) -> {
        CompletableFuture<List<NamespaceBundle>> updateFuture = new CompletableFuture<>();
        if (ex == null) {
            if (splitBoundaries == null || splitBoundaries.size() == 0) {
                LOG.info("[{}] No valid boundary found in {} to split bundle {}", bundle.getNamespaceObject().toString(), boundaries, bundle.getBundleRange());
                completionFuture.complete(null);
                return;
            }
            try {
                bundleFactory.splitBundles(bundle, splitBoundaries.size() + 1, splitBoundaries).thenAccept(splittedBundles -> {
                    // Zookeeper.
                    if (splittedBundles == null) {
                        String msg = format("bundle %s not found under namespace", bundle.toString());
                        LOG.warn(msg);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg));
                        return;
                    }
                    checkNotNull(splittedBundles.getLeft());
                    checkNotNull(splittedBundles.getRight());
                    checkArgument(splittedBundles.getRight().size() == splitBoundaries.size() + 1, "bundle has to be split in " + (splitBoundaries.size() + 1) + " bundles");
                    NamespaceName nsname = bundle.getNamespaceObject();
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("[{}] splitAndOwnBundleOnce: {}, counter: {}, bundles: {}", nsname.toString(), bundle.getBundleRange(), counter.get(), splittedBundles.getRight());
                    }
                    try {
                        // take ownership of newly split bundles
                        for (NamespaceBundle sBundle : splittedBundles.getRight()) {
                            checkNotNull(ownershipCache.tryAcquiringOwnership(sBundle));
                        }
                        updateNamespaceBundles(nsname, splittedBundles.getLeft()).thenRun(() -> {
                            bundleFactory.invalidateBundleCache(bundle.getNamespaceObject());
                            updateFuture.complete(splittedBundles.getRight());
                        }).exceptionally(ex1 -> {
                            String msg = format("failed to update namespace policies [%s], " + "NamespaceBundle: %s due to %s", nsname.toString(), bundle.getBundleRange(), ex1.getMessage());
                            LOG.warn(msg);
                            updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, ex1.getCause()));
                            return null;
                        });
                    } catch (Exception e) {
                        String msg = format("failed to acquire ownership of split bundle for namespace [%s], %s", nsname.toString(), e.getMessage());
                        LOG.warn(msg, e);
                        updateFuture.completeExceptionally(new ServiceUnitNotReadyException(msg, e));
                    }
                });
            } catch (Exception e) {
                updateFuture.completeExceptionally(e);
            }
        } else {
            updateFuture.completeExceptionally(ex);
        }
        // If success updateNamespaceBundles, then do invalidateBundleCache and unload.
        // Else retry splitAndOwnBundleOnceAndRetry.
        updateFuture.whenCompleteAsync((r, t) -> {
            if (t != null) {
                // retry several times on BadVersion
                if ((t.getCause() instanceof MetadataStoreException.BadVersionException) && (counter.decrementAndGet() >= 0)) {
                    pulsar.getOrderedExecutor().execute(() -> splitAndOwnBundleOnceAndRetry(bundle, unload, counter, completionFuture, splitAlgorithm, boundaries));
                } else if (t instanceof IllegalArgumentException) {
                    completionFuture.completeExceptionally(t);
                } else {
                    // Retry enough, or meet other exception
                    String msg2 = format(" %s not success update nsBundles, counter %d, reason %s", bundle.toString(), counter.get(), t.getMessage());
                    LOG.warn(msg2);
                    completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg2));
                }
                return;
            }
            // success updateNamespaceBundles
            // disable old bundle in memory
            getOwnershipCache().updateBundleState(bundle, false).thenRun(() -> {
                // update bundled_topic cache for load-report-generation
                pulsar.getBrokerService().refreshTopicToStatsMaps(bundle);
                loadManager.get().setLoadReportForceUpdateFlag();
                // release old bundle from ownership cache
                pulsar.getNamespaceService().getOwnershipCache().removeOwnership(bundle);
                completionFuture.complete(null);
                if (unload) {
                    // Unload new split bundles, in background. This will not
                    // affect the split operation which is already safely completed
                    r.forEach(this::unloadNamespaceBundle);
                }
            }).exceptionally(e -> {
                String msg1 = format("failed to disable bundle %s under namespace [%s] with error %s", bundle.getNamespaceObject().toString(), bundle.toString(), ex.getMessage());
                LOG.warn(msg1, e);
                completionFuture.completeExceptionally(new ServiceUnitNotReadyException(msg1));
                return null;
            });
        }, pulsar.getOrderedExecutor());
    });
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) CompletableFuture(java.util.concurrent.CompletableFuture) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) BundleSplitOption(org.apache.pulsar.common.naming.BundleSplitOption) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException)

Aggregations

List (java.util.List)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)3 ServiceUnitNotReadyException (org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException)3 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)3 BundleSplitOption (org.apache.pulsar.common.naming.BundleSplitOption)3 NamespaceBundle (org.apache.pulsar.common.naming.NamespaceBundle)3 NamespaceName (org.apache.pulsar.common.naming.NamespaceName)3 MetadataStoreException (org.apache.pulsar.metadata.api.MetadataStoreException)3