private synchronized void stop0()

in modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java [2131:2312]


        private synchronized void stop0(boolean cancel, ShutdownPolicy shutdown) {
            IgniteKernal grid0 = grid;

            // Double check.
            if (grid0 == null) {
                if (log != null)
                    U.warn(log, "Attempting to stop an already stopped Ignite instance (ignore): " + name);

                return;
            }

            if (shutdownHook != null) {
                try {
                    Runtime.getRuntime().removeShutdownHook(shutdownHook);

                    shutdownHook = null;

                    if (log != null && log.isDebugEnabled())
                        log.debug("Shutdown hook is removed.");
                }
                catch (IllegalStateException e) {
                    // Shutdown is in progress...
                    if (log != null && log.isDebugEnabled())
                        log.debug("Shutdown is in progress (ignoring): " + e.getMessage());
                }
            }

            if (shutdown == ShutdownPolicy.GRACEFUL && !grid.context().clientNode() && grid.cluster().state().active()) {
                delayedShutdown = true;

                if (log.isInfoEnabled())
                    log.info("Ensuring that caches have sufficient backups and local rebalance completion...");

                DistributedMetaStorage metaStorage = grid.context().distributedMetastorage();

                while (delayedShutdown) {
                    boolean safeToStop = true;

                    long topVer = grid.cluster().topologyVersion();

                    HashSet<UUID> originalNodesToExclude;

                    HashSet<UUID> nodesToExclude;

                    try {
                        originalNodesToExclude = metaStorage.read(GRACEFUL_SHUTDOWN_METASTORE_KEY);

                        nodesToExclude = originalNodesToExclude != null ? new HashSet<>(originalNodesToExclude) :
                            new HashSet<>();
                    }
                    catch (IgniteCheckedException e) {
                        U.error(log, "Unable to read " + GRACEFUL_SHUTDOWN_METASTORE_KEY +
                            " value from metastore.", e);

                        continue;
                    }

                    Map<UUID, Map<Integer, Set<Integer>>> proposedSuppliers = new HashMap<>();

                    for (CacheGroupContext grpCtx : grid.context().cache().cacheGroups()) {
                        if (grpCtx.systemCache())
                            continue;

                        if (grpCtx.config().getCacheMode() == PARTITIONED && grpCtx.config().getBackups() == 0) {
                            LT.warn(log, "Ignoring potential data loss on cache without backups [name="
                                + grpCtx.cacheOrGroupName() + "]");

                            continue;
                        }

                        if (topVer != grpCtx.topology().readyTopologyVersion().topologyVersion()) {
                            // At the moment, there is an exchange.
                            safeToStop = false;

                            break;
                        }

                        GridDhtPartitionFullMap fullMap = grpCtx.topology().partitionMap(false);

                        if (fullMap == null) {
                            safeToStop = false;

                            break;
                        }

                        nodesToExclude.retainAll(fullMap.keySet());

                        if (!haveCopyLocalPartitions(grpCtx, nodesToExclude, proposedSuppliers)) {
                            safeToStop = false;

                            if (log.isInfoEnabled()) {
                                LT.info(log, "This node is waiting for backups of local partitions for group [id="
                                    + grpCtx.groupId() + ", name=" + grpCtx.cacheOrGroupName() + "]");
                            }

                            break;
                        }

                        if (!isRebalanceCompleted(grpCtx)) {
                            safeToStop = false;

                            if (log.isInfoEnabled()) {
                                LT.info(log, "This node is waiting for completion of rebalance for group [id="
                                    + grpCtx.groupId() + ", name=" + grpCtx.cacheOrGroupName() + "]");
                            }

                            break;
                        }
                    }

                    if (topVer != grid.cluster().topologyVersion())
                        safeToStop = false;

                    if (safeToStop && !proposedSuppliers.isEmpty()) {
                        try {
                            safeToStop = grid0.context().task().execute(
                                CheckCpHistTask.class,
                                proposedSuppliers,
                                options(grid0.cluster().forNodeIds(proposedSuppliers.keySet()).nodes())
                            ).get();
                        }
                        catch (IgniteCheckedException e) {
                            U.error(log, "Failed to check availability of historical rebalance", e);

                            safeToStop = false;
                        }
                    }

                    if (safeToStop) {
                        try {
                            HashSet<UUID> newNodesToExclude = new HashSet<>(nodesToExclude);
                            newNodesToExclude.add(grid.localNodeId());

                            if (metaStorage.compareAndSet(GRACEFUL_SHUTDOWN_METASTORE_KEY, originalNodesToExclude,
                                newNodesToExclude))
                                break;
                        }
                        catch (IgniteCheckedException e) {
                            U.error(log, "Unable to write " + GRACEFUL_SHUTDOWN_METASTORE_KEY +
                                " value from metastore.", e);

                            continue;
                        }
                    }

                    try {
                        IgniteUtils.sleep(WAIT_FOR_BACKUPS_CHECK_INTERVAL);
                    }
                    catch (IgniteInterruptedCheckedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }

            // Unregister Ignite MBean.
            unregisterFactoryMBean();

            try {
                grid0.stop(cancel);

                if (log != null && log.isDebugEnabled())
                    log.debug("Ignite instance stopped ok: " + name);
            }
            catch (Throwable e) {
                U.error(log, "Failed to properly stop grid instance due to undeclared exception.", e);

                if (e instanceof Error)
                    throw e;
            }
            finally {
                if (grid0.context().segmented())
                    state = STOPPED_ON_SEGMENTATION;
                else if (grid0.context().invalid())
                    state = STOPPED_ON_FAILURE;
                else
                    state = STOPPED;

                grid = null;

                log = null;
            }
        }