| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.ignite.internal; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.lang.Thread.UncaughtExceptionHandler; |
| import java.lang.management.ManagementFactory; |
| import java.lang.reflect.Constructor; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.UUID; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ConcurrentMap; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.Executors; |
| import java.util.concurrent.LinkedBlockingQueue; |
| import java.util.concurrent.ScheduledExecutorService; |
| import java.util.concurrent.ThreadPoolExecutor; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| import java.util.logging.Handler; |
| import java.util.stream.Collectors; |
| import javax.management.JMException; |
| import javax.management.MBeanServer; |
| import javax.management.ObjectName; |
| import org.apache.ignite.Ignite; |
| import org.apache.ignite.IgniteCheckedException; |
| import org.apache.ignite.IgniteException; |
| import org.apache.ignite.IgniteIllegalStateException; |
| import org.apache.ignite.IgniteLogger; |
| import org.apache.ignite.IgniteState; |
| import org.apache.ignite.IgniteSystemProperties; |
| import org.apache.ignite.Ignition; |
| import org.apache.ignite.IgnitionListener; |
| import org.apache.ignite.ShutdownPolicy; |
| import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; |
| import org.apache.ignite.cluster.ClusterNode; |
| import org.apache.ignite.compute.ComputeJob; |
| import org.apache.ignite.configuration.CacheConfiguration; |
| import org.apache.ignite.configuration.ConnectorConfiguration; |
| import org.apache.ignite.configuration.DataRegionConfiguration; |
| import org.apache.ignite.configuration.DataStorageConfiguration; |
| import org.apache.ignite.configuration.DeploymentMode; |
| import org.apache.ignite.configuration.ExecutorConfiguration; |
| import org.apache.ignite.configuration.IgniteConfiguration; |
| import org.apache.ignite.configuration.MemoryConfiguration; |
| import org.apache.ignite.configuration.MemoryPolicyConfiguration; |
| import org.apache.ignite.configuration.PersistentStoreConfiguration; |
| import org.apache.ignite.configuration.TransactionConfiguration; |
| import org.apache.ignite.failure.FailureContext; |
| import org.apache.ignite.failure.FailureType; |
| import org.apache.ignite.internal.binary.BinaryMarshaller; |
| import org.apache.ignite.internal.managers.communication.GridIoPolicy; |
| import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; |
| import org.apache.ignite.internal.processors.cache.CacheGroupContext; |
| import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap; |
| import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap; |
| import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader; |
| import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState; |
| import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor; |
| import org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage; |
| import org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl; |
| import org.apache.ignite.internal.processors.resource.DependencyResolver; |
| import org.apache.ignite.internal.processors.resource.GridSpringResourceContext; |
| import org.apache.ignite.internal.util.GridConcurrentHashSet; |
| import org.apache.ignite.internal.util.IgniteUtils; |
| import org.apache.ignite.internal.util.StripedExecutor; |
| import org.apache.ignite.internal.util.TimeBag; |
| import org.apache.ignite.internal.util.spring.IgniteSpringHelper; |
| import org.apache.ignite.internal.util.typedef.CA; |
| import org.apache.ignite.internal.util.typedef.F; |
| import org.apache.ignite.internal.util.typedef.G; |
| import org.apache.ignite.internal.util.typedef.T2; |
| import org.apache.ignite.internal.util.typedef.X; |
| import org.apache.ignite.internal.util.typedef.internal.A; |
| import org.apache.ignite.internal.util.typedef.internal.CU; |
| import org.apache.ignite.internal.util.typedef.internal.LT; |
| import org.apache.ignite.internal.util.typedef.internal.S; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| import org.apache.ignite.internal.util.worker.GridWorker; |
| import org.apache.ignite.internal.worker.WorkersRegistry; |
| import org.apache.ignite.lang.IgniteBiInClosure; |
| import org.apache.ignite.lang.IgniteBiTuple; |
| import org.apache.ignite.lang.IgniteInClosure; |
| import org.apache.ignite.logger.LoggerNodeIdAware; |
| import org.apache.ignite.logger.java.JavaLogger; |
| import org.apache.ignite.marshaller.Marshaller; |
| import org.apache.ignite.marshaller.MarshallerUtils; |
| import org.apache.ignite.marshaller.jdk.JdkMarshaller; |
| import org.apache.ignite.mxbean.IgnitionMXBean; |
| import org.apache.ignite.plugin.segmentation.SegmentationPolicy; |
| import org.apache.ignite.resources.SpringApplicationContextResource; |
| import org.apache.ignite.spi.IgniteSpi; |
| import org.apache.ignite.spi.IgniteSpiMultipleInstancesSupport; |
| import org.apache.ignite.spi.checkpoint.noop.NoopCheckpointSpi; |
| import org.apache.ignite.spi.collision.noop.NoopCollisionSpi; |
| import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; |
| import org.apache.ignite.spi.deployment.local.LocalDeploymentSpi; |
| import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; |
| import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder; |
| import org.apache.ignite.spi.encryption.noop.NoopEncryptionSpi; |
| import org.apache.ignite.spi.eventstorage.NoopEventStorageSpi; |
| import org.apache.ignite.spi.failover.always.AlwaysFailoverSpi; |
| import org.apache.ignite.spi.indexing.noop.NoopIndexingSpi; |
| import org.apache.ignite.spi.loadbalancing.LoadBalancingSpi; |
| import org.apache.ignite.spi.loadbalancing.roundrobin.RoundRobinLoadBalancingSpi; |
| import org.apache.ignite.spi.metric.noop.NoopMetricExporterSpi; |
| import org.apache.ignite.spi.tracing.NoopTracingSpi; |
| import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor; |
| import org.apache.ignite.thread.IgniteThread; |
| import org.apache.ignite.thread.IgniteThreadPoolExecutor; |
| import org.jetbrains.annotations.Nullable; |
| |
| import static java.util.stream.Collectors.joining; |
| import static org.apache.ignite.IgniteState.STARTED; |
| import static org.apache.ignite.IgniteState.STOPPED; |
| import static org.apache.ignite.IgniteState.STOPPED_ON_FAILURE; |
| import static org.apache.ignite.IgniteState.STOPPED_ON_SEGMENTATION; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_CLIENT; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_CONFIG_URL; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_DEP_MODE_OVERRIDE; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_LOCAL_HOST; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_SHUTDOWN_HOOK; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_OVERRIDE_CONSISTENT_ID; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_RESTART_CODE; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_SUCCESS_FILE; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_SYSTEM_WORKER_BLOCKED_TIMEOUT; |
| import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; |
| import static org.apache.ignite.cache.CacheMode.PARTITIONED; |
| import static org.apache.ignite.cache.CacheMode.REPLICATED; |
| import static org.apache.ignite.cache.CacheRebalanceMode.SYNC; |
| import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; |
| import static org.apache.ignite.configuration.IgniteConfiguration.DFLT_THREAD_KEEP_ALIVE_TIME; |
| import static org.apache.ignite.configuration.MemoryConfiguration.DFLT_MEMORY_POLICY_MAX_SIZE; |
| import static org.apache.ignite.configuration.MemoryConfiguration.DFLT_MEM_PLC_DEFAULT_NAME; |
| import static org.apache.ignite.failure.FailureType.SYSTEM_WORKER_TERMINATION; |
| import static org.apache.ignite.internal.IgniteComponentType.SPRING; |
| import static org.apache.ignite.plugin.segmentation.SegmentationPolicy.RESTART_JVM; |
| |
| /** |
| * This class is part of an internal API and can be modified at any time without backward compatibility. |
| * |
| * This class defines a factory for the main Ignite API. It controls Grid life cycle |
| * and allows listening for grid events. |
| * <h1 class="header">Grid Loaders</h1> |
| * Although user can apply grid factory directly to start and stop grid, grid is |
| * often started and stopped by grid loaders. Grid loaders can be found in |
| * {@link org.apache.ignite.startup} package, for example: |
| * <ul> |
| * <li>{@code CommandLineStartup}</li> |
| * <li>{@code ServletStartup}</li> |
| * </ul> |
| * <h1 class="header">Examples</h1> |
| * Use {@link #start()} method to start grid with default configuration. You can also use |
| * {@link IgniteConfiguration} to override some default configuration. Below is an |
| * example on how to start grid with <strong>URI deployment</strong>. |
| * <pre name="code" class="java"> |
| * GridConfiguration cfg = new GridConfiguration(); |
| */ |
| public class IgnitionEx { |
| /** Default configuration path relative to Ignite home. */ |
| public static final String DFLT_CFG = "config/default-config.xml"; |
| |
| /** */ |
| private static final int WAIT_FOR_BACKUPS_CHECK_INTERVAL = 1000; |
| |
| /** Key to store list of gracefully stopping nodes within metastore. */ |
| private static final String GRACEFUL_SHUTDOWN_METASTORE_KEY = |
| DistributedMetaStorageImpl.IGNITE_INTERNAL_KEY_PREFIX + "graceful.shutdown"; |
| |
| /** Map of named Ignite instances. */ |
| private static final ConcurrentMap<Object, IgniteNamedInstance> grids = new ConcurrentHashMap<>(); |
| |
| /** Map of grid states ever started in this JVM. */ |
| private static final Map<Object, IgniteState> gridStates = new ConcurrentHashMap<>(); |
| |
| /** Mutex to synchronize updates of default grid reference. */ |
| private static final Object dfltGridMux = new Object(); |
| |
| /** Default grid. */ |
| private static volatile IgniteNamedInstance dfltGrid; |
| |
| /** Default grid state. */ |
| private static volatile IgniteState dfltGridState; |
| |
| /** List of state listeners. */ |
| private static final Collection<IgnitionListener> lsnrs = new GridConcurrentHashSet<>(4); |
| |
| /** */ |
| private static ThreadLocal<Boolean> daemon = new ThreadLocal<Boolean>() { |
| @Override protected Boolean initialValue() { |
| return false; |
| } |
| }; |
| |
| /** */ |
| private static ThreadLocal<Boolean> clientMode = new ThreadLocal<>(); |
| |
| /** Dependency container. */ |
| private static ThreadLocal<DependencyResolver> dependencyResolver = new ThreadLocal<>(); |
| |
| /** |
| * Enforces singleton. |
| */ |
| private IgnitionEx() { |
| // No-op. |
| } |
| |
| /** |
| * Sets daemon flag. |
| * <p> |
| * If daemon flag is set then all grid instances created by the factory will be |
| * daemon, i.e. the local node for these instances will be a daemon node. Note that |
| * if daemon flag is set - it will override the same settings in {@link IgniteConfiguration#isDaemon()}. |
| * Note that you can set on and off daemon flag at will. |
| * |
| * @param daemon Daemon flag to set. |
| */ |
| public static void setDaemon(boolean daemon) { |
| IgnitionEx.daemon.set(daemon); |
| } |
| |
| /** |
| * Gets daemon flag. |
| * <p> |
| * If daemon flag it set then all grid instances created by the factory will be |
| * daemon, i.e. the local node for these instances will be a daemon node. Note that |
| * if daemon flag is set - it will override the same settings in {@link IgniteConfiguration#isDaemon()}. |
| * Note that you can set on and off daemon flag at will. |
| * |
| * @return Daemon flag. |
| */ |
| public static boolean isDaemon() { |
| return daemon.get(); |
| } |
| |
| /** |
| * Sets client mode flag. |
| * |
| * @param clientMode Client mode flag. |
| */ |
| public static void setClientMode(boolean clientMode) { |
| IgnitionEx.clientMode.set(clientMode); |
| } |
| |
| /** |
| * Gets client mode flag. |
| * |
| * @return Client mode flag. |
| */ |
| public static boolean isClientMode() { |
| return clientMode.get() == null ? false : clientMode.get(); |
| } |
| |
| /** |
| * Gets state of grid default grid. |
| * |
| * @return Default grid state. |
| */ |
| public static IgniteState state() { |
| return state(null); |
| } |
| |
| /** |
| * Gets states of named Ignite instance. If name is {@code null}, then state of |
| * default no-name Ignite instance is returned. |
| * |
| * @param name Ignite instance name. If name is {@code null}, then state of |
| * default no-name Ignite instance is returned. |
| * @return Grid state. |
| */ |
| public static IgniteState state(@Nullable String name) { |
| IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid; |
| |
| if (grid == null) { |
| IgniteState state = name != null ? gridStates.get(name) : dfltGridState; |
| |
| return state != null ? state : STOPPED; |
| } |
| |
| return grid.state(); |
| } |
| |
| /** |
| * Stops default grid. This method is identical to {@code G.stop(null, cancel)} apply. |
| * Note that method does not wait for all tasks to be completed. |
| * |
| * @param cancel If {@code true} then all jobs currently executing on |
| * default grid will be cancelled by calling {@link ComputeJob#cancel()} |
| * method. Note that just like with {@link Thread#interrupt()}, it is |
| * up to the actual job to exit from execution |
| * @param shutdown If this parameter is set explicitly this policy will use for stopping node. |
| * If this parameter is {@code null} common cluster policy will be use. |
| * @return {@code true} if default grid instance was indeed stopped, |
| * {@code false} otherwise (if it was not started). |
| */ |
| public static boolean stop(boolean cancel, @Nullable ShutdownPolicy shutdown) { |
| return stop(null, cancel, shutdown, false); |
| } |
| |
| /** |
| * Stops named Ignite instance. If {@code cancel} flag is set to {@code true} then |
| * all jobs currently executing on local node will be interrupted. If |
| * Ignite instance name is {@code null}, then default no-name Ignite instance will be stopped. |
| * If wait parameter is set to {@code true} then Ignite instance will wait for all |
| * tasks to be finished. |
| * |
| * @param name Ignite instance name. If {@code null}, then default no-name |
| * Ignite instance will be stopped. |
| * @param cancel If {@code true} then all jobs currently will be cancelled |
| * by calling {@link ComputeJob#cancel()} method. Note that just like with |
| * {@link Thread#interrupt()}, it is up to the actual job to exit from |
| * execution. If {@code false}, then jobs currently running will not be |
| * canceled. In either case, grid node will wait for completion of all |
| * jobs running on it before stopping. |
| * @param shutdown If this parameter is set explicitly this policy will use for stopping node. |
| * If this parameter is {@code null} common cluster policy will be use. |
| * @param stopNotStarted If {@code true} and node start did not finish then interrupts starting thread. |
| * @return {@code true} if named Ignite instance was indeed found and stopped, |
| * {@code false} otherwise (the instance with given {@code name} was |
| * not found). |
| */ |
| public static boolean stop(@Nullable String name, boolean cancel, |
| @Nullable ShutdownPolicy shutdown, boolean stopNotStarted) { |
| IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid; |
| |
| if (grid != null && stopNotStarted && grid.startLatch.getCount() != 0) { |
| grid.starterThreadInterrupted = true; |
| |
| grid.starterThread.interrupt(); |
| } |
| |
| if (grid != null && grid.state() == STARTED) { |
| grid.stop(cancel, shutdown); |
| |
| boolean fireEvt; |
| |
| if (name != null) |
| fireEvt = grids.remove(name, grid); |
| else { |
| synchronized (dfltGridMux) { |
| fireEvt = dfltGrid == grid; |
| |
| if (fireEvt) |
| dfltGrid = null; |
| } |
| } |
| |
| if (fireEvt) |
| notifyStateChange(grid.getName(), grid.state()); |
| |
| return true; |
| } |
| |
| // We don't have log at this point... |
| U.warn(null, "Ignoring stopping Ignite instance that was already stopped or never started: " + name); |
| |
| return false; |
| } |
| |
| /** |
| * @deprecated |
| * |
| * Behavior of the method is the almost same as {@link IgnitionEx#stop(boolean, ShutdownPolicy)}. |
| * If node stopping process will not be finished within {@code timeoutMs} whole JVM will be killed. |
| * |
| * @param timeoutMs Timeout to wait graceful stopping. |
| */ |
| @Deprecated |
| public static boolean stop(@Nullable String name, boolean cancel, boolean stopNotStarted, long timeoutMs) { |
| final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); |
| |
| // Schedule delayed node killing if graceful stopping will be not finished within timeout. |
| executor.schedule(new Runnable() { |
| @Override public void run() { |
| if (state(name) == IgniteState.STARTED) { |
| U.error(null, "Unable to gracefully stop node within timeout " + timeoutMs + |
| " milliseconds. Killing node..."); |
| |
| // We are not able to kill only one grid so whole JVM will be stopped. |
| Runtime.getRuntime().halt(Ignition.KILL_EXIT_CODE); |
| } |
| } |
| }, timeoutMs, TimeUnit.MILLISECONDS); |
| |
| boolean success = stop(name, cancel, null, stopNotStarted); |
| |
| executor.shutdownNow(); |
| |
| return success; |
| } |
| |
| /** |
| * Stops <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then |
| * all jobs currently executing on local node will be interrupted. |
| * If wait parameter is set to {@code true} then grid will wait for all |
| * tasks to be finished. |
| * <p> |
| * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually |
| * instead of blanket operation. In most cases, the party that started the grid instance |
| * should be responsible for stopping it. |
| * |
| * @param cancel If {@code true} then all jobs currently executing on |
| * all grids will be cancelled by calling {@link ComputeJob#cancel()} |
| * method. Note that just like with {@link Thread#interrupt()}, it is |
| * up to the actual job to exit from execution |
| * @param shutdown If this parameter is set explicitly this policy will use for stopping node. |
| * If this parameter is {@code null} common cluster policy will be use. |
| */ |
| public static void stopAll(boolean cancel, @Nullable ShutdownPolicy shutdown) { |
| IgniteNamedInstance dfltGrid0 = dfltGrid; |
| |
| if (dfltGrid0 != null) { |
| dfltGrid0.stop(cancel, shutdown); |
| |
| boolean fireEvt; |
| |
| synchronized (dfltGridMux) { |
| fireEvt = dfltGrid == dfltGrid0; |
| |
| if (fireEvt) |
| dfltGrid = null; |
| } |
| |
| if (fireEvt) |
| notifyStateChange(dfltGrid0.getName(), dfltGrid0.state()); |
| } |
| |
| // Stop the rest and clear grids map. |
| for (IgniteNamedInstance grid : grids.values()) { |
| grid.stop(cancel, shutdown); |
| |
| boolean fireEvt = grids.remove(grid.getName(), grid); |
| |
| if (fireEvt) |
| notifyStateChange(grid.getName(), grid.state()); |
| } |
| } |
| |
| /** |
| * Restarts <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then |
| * all jobs currently executing on the local node will be interrupted. |
| * If {@code wait} parameter is set to {@code true} then grid will wait for all |
| * tasks to be finished. |
| * <p> |
| * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually |
| * instead of blanket operation. In most cases, the party that started the grid instance |
| * should be responsible for stopping it. |
| * <p> |
| * Note also that restarting functionality only works with the tools that specifically |
| * support Ignite's protocol for restarting. Currently only standard <tt>ignite.{sh|bat}</tt> |
| * scripts support restarting of JVM Ignite's process. |
| * |
| * @param cancel If {@code true} then all jobs currently executing on |
| * all grids will be cancelled by calling {@link ComputeJob#cancel()} |
| * method. Note that just like with {@link Thread#interrupt()}, it is |
| * up to the actual job to exit from execution. |
| * @see Ignition#RESTART_EXIT_CODE |
| */ |
| public static void restart(boolean cancel) { |
| String file = System.getProperty(IGNITE_SUCCESS_FILE); |
| |
| if (file == null) |
| U.warn(null, "Cannot restart node when restart not enabled."); |
| else { |
| try { |
| new File(file).createNewFile(); |
| } |
| catch (IOException e) { |
| U.error(null, "Failed to create restart marker file (restart aborted): " + e.getMessage()); |
| |
| return; |
| } |
| |
| U.log(null, "Restarting node. Will exit (" + Ignition.RESTART_EXIT_CODE + ")."); |
| |
| // Set the exit code so that shell process can recognize it and loop |
| // the start up sequence again. |
| System.setProperty(IGNITE_RESTART_CODE, Integer.toString(Ignition.RESTART_EXIT_CODE)); |
| |
| stopAll(cancel, null); |
| |
| // This basically leaves loaders hang - we accept it. |
| System.exit(Ignition.RESTART_EXIT_CODE); |
| } |
| } |
| |
| /** |
| * Stops <b>all</b> started grids. If {@code cancel} flag is set to {@code true} then |
| * all jobs currently executing on the local node will be interrupted. |
| * If {@code wait} parameter is set to {@code true} then grid will wait for all |
| * tasks to be finished. |
| * <p> |
| * <b>Note:</b> it is usually safer and more appropriate to stop grid instances individually |
| * instead of blanket operation. In most cases, the party that started the grid instance |
| * should be responsible for stopping it. |
| * <p> |
| * Note that upon completion of this method, the JVM with forcefully exist with |
| * exit code {@link Ignition#KILL_EXIT_CODE}. |
| * |
| * @param cancel If {@code true} then all jobs currently executing on |
| * all grids will be cancelled by calling {@link ComputeJob#cancel()} |
| * method. Note that just like with {@link Thread#interrupt()}, it is |
| * up to the actual job to exit from execution. |
| * @see Ignition#KILL_EXIT_CODE |
| */ |
| public static void kill(boolean cancel) { |
| stopAll(cancel, null); |
| |
| // This basically leaves loaders hang - we accept it. |
| System.exit(Ignition.KILL_EXIT_CODE); |
| } |
| |
| /** |
| * Starts grid with default configuration. By default this method will |
| * use grid configuration defined in {@code IGNITE_HOME/config/default-config.xml} |
| * configuration file. If such file is not found, then all system defaults will be used. |
| * |
| * @return Started grid. |
| * @throws IgniteCheckedException If default grid could not be started. This exception will be thrown |
| * also if default grid has already been started. |
| */ |
| public static Ignite start() throws IgniteCheckedException { |
| return start((GridSpringResourceContext)null); |
| } |
| |
| /** |
| * Starts grid with default configuration. By default this method will |
| * use grid configuration defined in {@code IGNITE_HOME/config/default-config.xml} |
| * configuration file. If such file is not found, then all system defaults will be used. |
| * |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @return Started grid. |
| * @throws IgniteCheckedException If default grid could not be started. This exception will be thrown |
| * also if default grid has already been started. |
| */ |
| public static Ignite start(@Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException { |
| URL url = U.resolveIgniteUrl(DFLT_CFG); |
| |
| if (url != null) |
| return start(DFLT_CFG, null, springCtx, null); |
| |
| U.warn(null, "Default Spring XML file not found (is IGNITE_HOME set?): " + DFLT_CFG); |
| |
| return start0(new GridStartContext(new IgniteConfiguration(), null, springCtx), true) |
| .get1().grid(); |
| } |
| |
| /** |
| * Starts grid with given configuration. Note that this method is no-op if grid with the name |
| * provided in given configuration is already started. |
| * |
| * @param cfg Grid configuration. This cannot be {@code null}. |
| * @return Started grid. |
| * @throws IgniteCheckedException If grid could not be started. This exception will be thrown |
| * also if named grid has already been started. |
| */ |
| public static Ignite start(IgniteConfiguration cfg) throws IgniteCheckedException { |
| return start(cfg, null, true).get1(); |
| } |
| |
| /** |
| * Starts a grid with given configuration. If the grid is already started and failIfStarted set to TRUE |
| * an exception will be thrown. |
| * |
| * @param cfg Grid configuration. This cannot be {@code null}. |
| * @param failIfStarted When flag is {@code true} and grid with specified name has been already started |
| * the exception is thrown. Otherwise the existing instance of the grid is returned. |
| * @return Started grid or existing grid. |
| * @throws IgniteCheckedException If grid could not be started. This exception will be thrown |
| * also if named grid has already been started. |
| */ |
| public static Ignite start(IgniteConfiguration cfg, boolean failIfStarted) throws IgniteCheckedException { |
| return start(cfg, null, failIfStarted).get1(); |
| } |
| |
| /** |
| * Gets or starts new grid instance if it hasn't been started yet. |
| * |
| * @param cfg Grid configuration. This cannot be {@code null}. |
| * @return Tuple with: grid instance and flag to indicate the instance is started by this call. |
| * So, when the new ignite instance is started the flag is {@code true}. If an existing instance is returned |
| * the flag is {@code false}. |
| * @throws IgniteException If grid could not be started. |
| */ |
| public static T2<Ignite, Boolean> getOrStart(IgniteConfiguration cfg) throws IgniteException { |
| try { |
| return start(cfg, null, false); |
| } |
| catch (IgniteCheckedException e) { |
| throw U.convertException(e); |
| } |
| } |
| |
| /** |
| * Starts grid with given configuration. Note that this method will throw and exception if grid with the name |
| * provided in given configuration is already started. |
| * |
| * @param cfg Grid configuration. This cannot be {@code null}. |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @return Started grid. |
| * @throws IgniteCheckedException If grid could not be started. This exception will be thrown |
| * also if named grid has already been started. |
| */ |
| public static Ignite start(IgniteConfiguration cfg, @Nullable GridSpringResourceContext springCtx) throws IgniteCheckedException { |
| A.notNull(cfg, "cfg"); |
| |
| return start0(new GridStartContext(cfg, null, springCtx), true).get1().grid(); |
| } |
| |
| /** |
| * Starts grid with given configuration. If the grid is already started and failIfStarted set to TRUE |
| * an exception will be thrown. |
| * |
| * @param cfg Grid configuration. This cannot be {@code null}. |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @param failIfStarted Throw or not an exception if grid is already started. |
| * @return Tuple with: grid instance and flag to indicate the instance is started by this call. |
| * So, when the new ignite instance is started the flag is {@code true}. If an existing instance is returned |
| * the flag is {@code false}. |
| * @throws IgniteCheckedException If grid could not be started. This exception will be thrown |
| * also if named grid has already been started. |
| */ |
| public static T2<Ignite, Boolean> start(IgniteConfiguration cfg, @Nullable GridSpringResourceContext springCtx, boolean failIfStarted) throws IgniteCheckedException { |
| A.notNull(cfg, "cfg"); |
| |
| T2<IgniteNamedInstance, Boolean> res = start0(new GridStartContext(cfg, null, springCtx), failIfStarted); |
| |
| return new T2<>((Ignite)res.get1().grid(), res.get2()); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgPath Spring XML configuration file path or URL. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(@Nullable String springCfgPath) throws IgniteCheckedException { |
| return springCfgPath == null ? start() : start(springCfgPath, null); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgPath Spring XML configuration file path or URL. |
| * @param igniteInstanceName Ignite instance name that will override default. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(@Nullable String springCfgPath, @Nullable String igniteInstanceName) |
| throws IgniteCheckedException { |
| if (springCfgPath == null) { |
| IgniteConfiguration cfg = new IgniteConfiguration(); |
| |
| if (cfg.getIgniteInstanceName() == null && !F.isEmpty(igniteInstanceName)) |
| cfg.setIgniteInstanceName(igniteInstanceName); |
| |
| return start(cfg); |
| } |
| else |
| return start(springCfgPath, igniteInstanceName, null, null); |
| } |
| |
| /** |
| * Loads all grid configurations specified within given Spring XML configuration file. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgUrl Spring XML configuration file path or URL. This cannot be {@code null}. |
| * @return Tuple containing all loaded configurations and Spring context used to load them. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> |
| loadConfigurations(URL springCfgUrl) throws IgniteCheckedException { |
| IgniteSpringHelper spring = SPRING.create(false); |
| |
| return spring.loadConfigurations(springCfgUrl); |
| } |
| |
| /** |
| * Loads all grid configurations specified within given input stream. |
| * <p> |
| * Usually Spring XML input stream will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration input stream by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgStream Input stream contained Spring XML configuration. This cannot be {@code null}. |
| * @return Tuple containing all loaded configurations and Spring context used to load them. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> |
| loadConfigurations(InputStream springCfgStream) throws IgniteCheckedException { |
| IgniteSpringHelper spring = SPRING.create(false); |
| |
| return spring.loadConfigurations(springCfgStream); |
| } |
| |
| /** |
| * Loads all grid configurations specified within given Spring XML configuration file. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgPath Spring XML configuration file path. This cannot be {@code null}. |
| * @return Tuple containing all loaded configurations and Spring context used to load them. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> |
| loadConfigurations(String springCfgPath) throws IgniteCheckedException { |
| A.notNull(springCfgPath, "springCfgPath"); |
| return loadConfigurations(IgniteUtils.resolveSpringUrl(springCfgPath)); |
| } |
| |
| /** |
| * Loads first found grid configuration specified within given Spring XML configuration file. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgUrl Spring XML configuration file path or URL. This cannot be {@code null}. |
| * @return First found configuration and Spring context used to load it. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static IgniteBiTuple<IgniteConfiguration, GridSpringResourceContext> loadConfiguration(URL springCfgUrl) |
| throws IgniteCheckedException { |
| IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> t = |
| loadConfigurations(springCfgUrl); |
| |
| return F.t(F.first(t.get1()), t.get2()); |
| } |
| |
| /** |
| * Loads first found grid configuration specified within given Spring XML configuration file. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgPath Spring XML configuration file path. This cannot be {@code null}. |
| * @return First found configuration and Spring context used to load it. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static IgniteBiTuple<IgniteConfiguration, GridSpringResourceContext> loadConfiguration(String springCfgPath) |
| throws IgniteCheckedException { |
| IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> t = |
| loadConfigurations(springCfgPath); |
| |
| return F.t(F.first(t.get1()), t.get2()); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgPath Spring XML configuration file path or URL. This cannot be {@code null}. |
| * @param igniteInstanceName Ignite instance name that will override default. |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * @param ldr Optional class loader that will be used by default. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(String springCfgPath, @Nullable String igniteInstanceName, |
| @Nullable GridSpringResourceContext springCtx, @Nullable ClassLoader ldr) throws IgniteCheckedException { |
| URL url = U.resolveSpringUrl(springCfgPath); |
| |
| return start(url, igniteInstanceName, springCtx, ldr); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file URL. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(URL springCfgUrl) throws IgniteCheckedException { |
| return start(springCfgUrl, null, null, null); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file URL. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}. |
| * @param ldr Optional class loader that will be used by default. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(URL springCfgUrl, @Nullable ClassLoader ldr) throws IgniteCheckedException { |
| return start(springCfgUrl, null, null, ldr); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration file URL. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration file will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration file by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgUrl Spring XML configuration file URL. This cannot be {@code null}. |
| * @param igniteInstanceName Ignite instance name that will override default. |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * @param ldr Optional class loader that will be used by default. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(URL springCfgUrl, @Nullable String igniteInstanceName, |
| @Nullable GridSpringResourceContext springCtx, @Nullable ClassLoader ldr) throws IgniteCheckedException { |
| A.notNull(springCfgUrl, "springCfgUrl"); |
| |
| boolean isLog4jUsed = U.gridClassLoader().getResource("org/apache/log4j/Appender.class") != null; |
| |
| IgniteBiTuple<Object, Object> t = null; |
| |
| if (isLog4jUsed) { |
| try { |
| t = U.addLog4jNoOpLogger(); |
| } |
| catch (IgniteCheckedException ignore) { |
| isLog4jUsed = false; |
| } |
| } |
| |
| Collection<Handler> savedHnds = null; |
| |
| if (!isLog4jUsed) |
| savedHnds = U.addJavaNoOpLogger(); |
| |
| IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> cfgMap; |
| |
| try { |
| cfgMap = loadConfigurations(springCfgUrl); |
| } |
| finally { |
| if (isLog4jUsed && t != null) |
| U.removeLog4jNoOpLogger(t); |
| |
| if (!isLog4jUsed) |
| U.removeJavaNoOpLogger(savedHnds); |
| } |
| |
| return startConfigurations(cfgMap, springCfgUrl, igniteInstanceName, springCtx, ldr); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration input stream. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration input stream will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration input stream by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgStream Input stream containing Spring XML configuration. This cannot be {@code null}. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(InputStream springCfgStream) throws IgniteCheckedException { |
| return start(springCfgStream, null, null, null); |
| } |
| |
| /** |
| * Starts all grids specified within given Spring XML configuration input stream. If grid with given name |
| * is already started, then exception is thrown. In this case all instances that may |
| * have been started so far will be stopped too. |
| * <p> |
| * Usually Spring XML configuration input stream will contain only one Grid definition. Note that |
| * Grid configuration bean(s) is retrieved form configuration input stream by type, so the name of |
| * the Grid configuration bean is ignored. |
| * |
| * @param springCfgStream Input stream containing Spring XML configuration. This cannot be {@code null}. |
| * @param igniteInstanceName Ignite instance name that will override default. |
| * @param springCtx Optional Spring application context, possibly {@code null}. |
| * @param ldr Optional class loader that will be used by default. |
| * Spring bean definitions for bean injection are taken from this context. |
| * If provided, this context can be injected into grid tasks and grid jobs using |
| * {@link SpringApplicationContextResource @SpringApplicationContextResource} annotation. |
| * @return Started grid. If Spring configuration contains multiple grid instances, |
| * then the 1st found instance is returned. |
| * @throws IgniteCheckedException If grid could not be started or configuration |
| * read. This exception will be thrown also if grid with given name has already |
| * been started or Spring XML configuration file is invalid. |
| */ |
| public static Ignite start(InputStream springCfgStream, @Nullable String igniteInstanceName, |
| @Nullable GridSpringResourceContext springCtx, @Nullable ClassLoader ldr) throws IgniteCheckedException { |
| A.notNull(springCfgStream, "springCfgUrl"); |
| |
| boolean isLog4jUsed = U.gridClassLoader().getResource("org/apache/log4j/Appender.class") != null; |
| |
| IgniteBiTuple<Object, Object> t = null; |
| |
| if (isLog4jUsed) { |
| try { |
| t = U.addLog4jNoOpLogger(); |
| } |
| catch (IgniteCheckedException ignore) { |
| isLog4jUsed = false; |
| } |
| } |
| |
| Collection<Handler> savedHnds = null; |
| |
| if (!isLog4jUsed) |
| savedHnds = U.addJavaNoOpLogger(); |
| |
| IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> cfgMap; |
| |
| try { |
| cfgMap = loadConfigurations(springCfgStream); |
| } |
| finally { |
| if (isLog4jUsed && t != null) |
| U.removeLog4jNoOpLogger(t); |
| |
| if (!isLog4jUsed) |
| U.removeJavaNoOpLogger(savedHnds); |
| } |
| |
| return startConfigurations(cfgMap, null, igniteInstanceName, springCtx, ldr); |
| } |
| |
| /** |
| * Internal Spring-based start routine. Starts loaded configurations. |
| * |
| * @param cfgMap Configuration map. |
| * @param springCfgUrl Spring XML configuration file URL. |
| * @param igniteInstanceName Ignite instance name that will override default. |
| * @param springCtx Optional Spring application context. |
| * @param ldr Optional class loader that will be used by default. |
| * @return Started grid. |
| * @throws IgniteCheckedException If failed. |
| */ |
| private static Ignite startConfigurations( |
| IgniteBiTuple<Collection<IgniteConfiguration>, ? extends GridSpringResourceContext> cfgMap, |
| URL springCfgUrl, |
| @Nullable String igniteInstanceName, |
| @Nullable GridSpringResourceContext springCtx, |
| @Nullable ClassLoader ldr) |
| throws IgniteCheckedException { |
| List<IgniteNamedInstance> grids = new ArrayList<>(cfgMap.size()); |
| |
| try { |
| for (IgniteConfiguration cfg : cfgMap.get1()) { |
| assert cfg != null; |
| |
| if (cfg.getIgniteInstanceName() == null && !F.isEmpty(igniteInstanceName)) |
| cfg.setIgniteInstanceName(igniteInstanceName); |
| |
| if (ldr != null && cfg.getClassLoader() == null) |
| cfg.setClassLoader(ldr); |
| |
| // Use either user defined context or our one. |
| IgniteNamedInstance grid = start0( |
| new GridStartContext(cfg, springCfgUrl, springCtx == null |
| ? cfgMap.get2() : springCtx), true).get1(); |
| |
| // Add it if it was not stopped during startup. |
| if (grid != null) |
| grids.add(grid); |
| } |
| } |
| catch (IgniteCheckedException e) { |
| // Stop all instances started so far. |
| for (IgniteNamedInstance grid : grids) { |
| try { |
| grid.stop(true, ShutdownPolicy.IMMEDIATE); |
| } |
| catch (Exception e1) { |
| U.error(grid.log, "Error when stopping grid: " + grid, e1); |
| } |
| } |
| |
| throw e; |
| } |
| |
| // Return the first grid started. |
| IgniteNamedInstance res = !grids.isEmpty() ? grids.get(0) : null; |
| |
| return res != null ? res.grid() : null; |
| } |
| |
| /** |
| * Starts grid with given configuration. |
| * |
| * @param startCtx Start context. |
| * @param failIfStarted Throw or not an exception if grid is already started. |
| * @return Tuple with: grid instance and flag to indicate the instance is started by this call. |
| * So, when the new ignite instance is started the flag is {@code true}. If an existing instance is returned |
| * the flag is {@code false}. |
| * @throws IgniteCheckedException If grid could not be started. |
| */ |
| private static T2<IgniteNamedInstance, Boolean> start0(GridStartContext startCtx, boolean failIfStarted ) throws IgniteCheckedException { |
| assert startCtx != null; |
| |
| String name = startCtx.config().getIgniteInstanceName(); |
| |
| if (name != null && name.isEmpty()) |
| throw new IgniteCheckedException("Non default Ignite instances cannot have empty string name."); |
| |
| IgniteNamedInstance grid = new IgniteNamedInstance(name); |
| |
| IgniteNamedInstance old; |
| |
| if (name != null) |
| old = grids.putIfAbsent(name, grid); |
| else { |
| synchronized (dfltGridMux) { |
| old = dfltGrid; |
| |
| if (old == null) |
| dfltGrid = grid; |
| } |
| } |
| |
| if (old != null) |
| if (old.grid() == null) { // Stopped but not removed from map yet. |
| boolean replaced; |
| |
| if (name != null) |
| replaced = grids.replace(name, old, grid); |
| else { |
| synchronized (dfltGridMux) { |
| replaced = old == dfltGrid; |
| |
| if (replaced) |
| dfltGrid = grid; |
| } |
| } |
| |
| if (!replaced) { |
| throw new IgniteCheckedException("Ignite instance with this name has been concurrently started: " + |
| name); |
| } |
| else |
| notifyStateChange(old.getName(), old.state()); |
| } |
| else if (failIfStarted) { |
| if (name == null) |
| throw new IgniteCheckedException("Default Ignite instance has already been started."); |
| else |
| throw new IgniteCheckedException("Ignite instance with this name has already been started: " + |
| name); |
| } |
| else |
| return new T2<>(old, false); |
| |
| if (startCtx.config().getWarmupClosure() != null) |
| startCtx.config().getWarmupClosure().apply(startCtx.config()); |
| |
| startCtx.single(grids.size() == 1); |
| |
| boolean success = false; |
| |
| try { |
| try { |
| grid.start(startCtx); |
| } |
| catch (Exception e) { |
| if (X.hasCause(e, IgniteInterruptedCheckedException.class, InterruptedException.class)) { |
| if (grid.starterThreadInterrupted) |
| Thread.interrupted(); |
| } |
| |
| throw e; |
| } |
| |
| notifyStateChange(name, STARTED); |
| |
| success = true; |
| } |
| finally { |
| if (!success) { |
| if (name != null) |
| grids.remove(name, grid); |
| else { |
| synchronized (dfltGridMux) { |
| if (dfltGrid == grid) |
| dfltGrid = null; |
| } |
| } |
| |
| grid = null; |
| } |
| } |
| |
| if (grid == null) |
| throw new IgniteCheckedException("Failed to start grid with provided configuration."); |
| |
| return new T2<>(grid, true); |
| } |
| |
| /** |
| * Loads spring bean by name. |
| * |
| * @param springXmlPath Spring XML file path. |
| * @param beanName Bean name. |
| * @return Bean instance. |
| * @throws IgniteCheckedException In case of error. |
| */ |
| public static <T> T loadSpringBean(String springXmlPath, String beanName) throws IgniteCheckedException { |
| A.notNull(springXmlPath, "springXmlPath"); |
| A.notNull(beanName, "beanName"); |
| |
| URL url = U.resolveSpringUrl(springXmlPath); |
| |
| assert url != null; |
| |
| return loadSpringBean(url, beanName); |
| } |
| |
| /** |
| * Loads spring bean by name. |
| * |
| * @param springXmlUrl Spring XML file URL. |
| * @param beanName Bean name. |
| * @return Bean instance. |
| * @throws IgniteCheckedException In case of error. |
| */ |
| public static <T> T loadSpringBean(URL springXmlUrl, String beanName) throws IgniteCheckedException { |
| A.notNull(springXmlUrl, "springXmlUrl"); |
| A.notNull(beanName, "beanName"); |
| |
| IgniteSpringHelper spring = SPRING.create(false); |
| |
| return spring.loadBean(springXmlUrl, beanName); |
| } |
| |
| /** |
| * Loads spring bean by name. |
| * |
| * @param springXmlStream Input stream containing Spring XML configuration. |
| * @param beanName Bean name. |
| * @return Bean instance. |
| * @throws IgniteCheckedException In case of error. |
| */ |
| public static <T> T loadSpringBean(InputStream springXmlStream, String beanName) throws IgniteCheckedException { |
| A.notNull(springXmlStream, "springXmlPath"); |
| A.notNull(beanName, "beanName"); |
| |
| IgniteSpringHelper spring = SPRING.create(false); |
| |
| return spring.loadBean(springXmlStream, beanName); |
| } |
| |
| /** |
| * Gets an instance of default no-name grid. Note that |
| * caller of this method should not assume that it will return the same |
| * instance every time. |
| * |
| * @return An instance of default no-name grid. This method never returns |
| * {@code null}. |
| * @throws IgniteIllegalStateException Thrown if default grid was not properly |
| * initialized or grid instance was stopped or was not started. |
| */ |
| public static Ignite grid() throws IgniteIllegalStateException { |
| return grid((String)null); |
| } |
| |
| /** |
| * Gets a list of all grids started so far. |
| * |
| * @return List of all grids started so far. |
| */ |
| public static List<Ignite> allGrids() { |
| return allGrids(true); |
| } |
| |
| /** |
| * Gets a list of all grids started so far. |
| * |
| * @return List of all grids started so far. |
| */ |
| public static List<Ignite> allGridsx() { |
| return allGrids(false); |
| } |
| |
| /** |
| * Gets a list of all grids started so far. |
| * |
| * @param wait If {@code true} wait for node start finish. |
| * @return List of all grids started so far. |
| */ |
| private static List<Ignite> allGrids(boolean wait) { |
| List<Ignite> allIgnites = new ArrayList<>(grids.size() + 1); |
| |
| for (IgniteNamedInstance grid : grids.values()) { |
| Ignite g = wait ? grid.grid() : grid.gridx(); |
| |
| if (g != null) |
| allIgnites.add(g); |
| } |
| |
| IgniteNamedInstance dfltGrid0 = dfltGrid; |
| |
| if (dfltGrid0 != null) { |
| IgniteKernal g = wait ? dfltGrid0.grid() : dfltGrid0.gridx(); |
| |
| if (g != null) |
| allIgnites.add(g); |
| } |
| |
| return allIgnites; |
| } |
| |
| /** |
| * Gets a grid instance for given local node ID. Note that grid instance and local node have |
| * one-to-one relationship where node has ID and instance has name of the grid to which |
| * both grid instance and its node belong. Note also that caller of this method |
| * should not assume that it will return the same instance every time. |
| * |
| * @param locNodeId ID of local node the requested grid instance is managing. |
| * @return An instance of named grid. This method never returns |
| * {@code null}. |
| * @throws IgniteIllegalStateException Thrown if grid was not properly |
| * initialized or grid instance was stopped or was not started. |
| */ |
| public static Ignite grid(UUID locNodeId) throws IgniteIllegalStateException { |
| A.notNull(locNodeId, "locNodeId"); |
| |
| IgniteNamedInstance dfltGrid0 = dfltGrid; |
| |
| if (dfltGrid0 != null) { |
| IgniteKernal g = dfltGrid0.grid(); |
| |
| if (g != null && g.getLocalNodeId().equals(locNodeId)) |
| return g; |
| } |
| |
| for (IgniteNamedInstance grid : grids.values()) { |
| IgniteKernal g = grid.grid(); |
| |
| if (g != null && g.getLocalNodeId().equals(locNodeId)) |
| return g; |
| } |
| |
| throw new IgniteIllegalStateException("Grid instance with given local node ID was not properly " + |
| "started or was stopped: " + locNodeId); |
| } |
| |
| /** |
| * Gets grid instance without waiting its initialization and not throwing any exception. |
| * |
| * @param locNodeId ID of local node the requested grid instance is managing. |
| * @return Grid instance or {@code null}. |
| */ |
| public static IgniteKernal gridxx(UUID locNodeId) { |
| IgniteNamedInstance dfltGrid0 = dfltGrid; |
| |
| if (dfltGrid0 != null) { |
| IgniteKernal g = dfltGrid0.grid(); |
| |
| if (g != null && g.getLocalNodeId().equals(locNodeId)) |
| return g; |
| } |
| |
| for (IgniteNamedInstance grid : grids.values()) { |
| IgniteKernal g = grid.grid(); |
| |
| if (g != null && g.getLocalNodeId().equals(locNodeId)) |
| return g; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Gets an named grid instance. If grid name is {@code null} or empty string, |
| * then default no-name grid will be returned. Note that caller of this method |
| * should not assume that it will return the same instance every time. |
| * <p> |
| * Note that Java VM can run multiple grid instances and every grid instance (and its |
| * node) can belong to a different grid. Grid name defines what grid a particular grid |
| * instance (and correspondingly its node) belongs to. |
| * |
| * @param name Grid name to which requested grid instance belongs to. If {@code null}, |
| * then grid instance belonging to a default no-name grid will be returned. |
| * @return An instance of named grid. This method never returns |
| * {@code null}. |
| * @throws IgniteIllegalStateException Thrown if default grid was not properly |
| * initialized or grid instance was stopped or was not started. |
| */ |
| public static Ignite grid(@Nullable String name) throws IgniteIllegalStateException { |
| IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid; |
| |
| Ignite res; |
| |
| if (grid == null || (res = grid.grid()) == null) |
| throw new IgniteIllegalStateException("Ignite instance with provided name doesn't exist. " + |
| "Did you call Ignition.start(..) to start an Ignite instance? [name=" + name + ']'); |
| |
| return res; |
| } |
| |
| /** |
| * Gets a name of the grid from thread local config, which is owner of current thread. |
| * |
| * @return Grid instance related to current thread |
| * @throws IllegalArgumentException Thrown to indicate, that current thread is not an {@link IgniteThread}. |
| */ |
| public static IgniteKernal localIgnite() throws IllegalArgumentException { |
| String name = U.getCurrentIgniteName(); |
| |
| if (U.isCurrentIgniteNameSet(name)) |
| return gridx(name); |
| else if (Thread.currentThread() instanceof IgniteThread) |
| return gridx(((IgniteThread)Thread.currentThread()).getIgniteInstanceName()); |
| else |
| throw new IllegalArgumentException("Ignite instance name thread local must be set or" + |
| " this method should be accessed under " + IgniteThread.class.getName()); |
| } |
| |
| /** |
| * Gets grid instance without waiting its initialization. |
| * |
| * @param name Grid name. |
| * @return Grid instance. |
| */ |
| public static IgniteKernal gridx(@Nullable String name) { |
| IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid; |
| |
| IgniteKernal res; |
| |
| if (grid == null || (res = grid.gridx()) == null) |
| throw new IgniteIllegalStateException("Ignite instance with provided name doesn't exist. " + |
| "Did you call Ignition.start(..) to start an Ignite instance? [name=" + name + ']'); |
| |
| return res; |
| } |
| |
| /** |
| * Adds a lsnr for grid life cycle events. |
| * <p> |
| * Note that unlike other listeners in Ignite this listener will be |
| * notified from the same thread that triggers the state change. Because of |
| * that it is the responsibility of the user to make sure that listener logic |
| * is light-weight and properly handles (catches) any runtime exceptions, if any |
| * are expected. |
| * |
| * @param lsnr Listener for grid life cycle events. If this listener was already added |
| * this method is no-op. |
| */ |
| public static void addListener(IgnitionListener lsnr) { |
| A.notNull(lsnr, "lsnr"); |
| |
| lsnrs.add(lsnr); |
| } |
| |
| /** |
| * Removes lsnr added by {@link #addListener(IgnitionListener)} method. |
| * |
| * @param lsnr Listener to remove. |
| * @return {@code true} if lsnr was added before, {@code false} otherwise. |
| */ |
| public static boolean removeListener(IgnitionListener lsnr) { |
| A.notNull(lsnr, "lsnr"); |
| |
| return lsnrs.remove(lsnr); |
| } |
| |
| /** |
| * @param igniteInstanceName Ignite instance name. |
| * @param state Factory state. |
| */ |
| private static void notifyStateChange(@Nullable String igniteInstanceName, IgniteState state) { |
| if (igniteInstanceName != null) |
| gridStates.put(igniteInstanceName, state); |
| else |
| dfltGridState = state; |
| |
| for (IgnitionListener lsnr : lsnrs) |
| lsnr.onStateChange(igniteInstanceName, state); |
| } |
| |
| /** |
| * Sets custom dependency resolver which provides overridden dependencies |
| * |
| * @param rslvr Dependency resolver. |
| */ |
| public static void dependencyResolver(DependencyResolver rslvr) { |
| dependencyResolver.set(rslvr); |
| } |
| |
| /** |
| * Custom dependency resolver. |
| * |
| * @return Returns {@code null} if resolver wasn't added. |
| */ |
| public static DependencyResolver dependencyResolver() { |
| return dependencyResolver.get(); |
| } |
| |
| /** |
| * @param name Grid name (possibly {@code null} for default grid). |
| * @return true when all managers, processors, and plugins have started and ignite kernal start method has fully |
| * completed. |
| */ |
| public static boolean hasKernalStarted(String name) { |
| IgniteNamedInstance grid = name != null ? grids.get(name) : dfltGrid; |
| return grid != null && grid.hasStartLatchCompleted(); |
| } |
| |
| /** |
| * Start context encapsulates all starting parameters. |
| */ |
| private static final class GridStartContext { |
| /** User-defined configuration. */ |
| private IgniteConfiguration cfg; |
| |
| /** Optional configuration path. */ |
| private URL cfgUrl; |
| |
| /** Optional Spring application context. */ |
| private GridSpringResourceContext springCtx; |
| |
| /** Whether or not this is a single grid instance in current VM. */ |
| private boolean single; |
| |
| /** |
| * |
| * @param cfg User-defined configuration. |
| * @param cfgUrl Optional configuration path. |
| * @param springCtx Optional Spring application context. |
| */ |
| GridStartContext(IgniteConfiguration cfg, @Nullable URL cfgUrl, @Nullable GridSpringResourceContext springCtx) { |
| assert (cfg != null); |
| |
| this.cfg = cfg; |
| this.cfgUrl = cfgUrl; |
| this.springCtx = springCtx; |
| } |
| |
| /** |
| * @return Whether or not this is a single grid instance in current VM. |
| */ |
| public boolean single() { |
| return single; |
| } |
| |
| /** |
| * @param single Whether or not this is a single grid instance in current VM. |
| */ |
| public void single(boolean single) { |
| this.single = single; |
| } |
| |
| /** |
| * @return User-defined configuration. |
| */ |
| IgniteConfiguration config() { |
| return cfg; |
| } |
| |
| /** |
| * @param cfg User-defined configuration. |
| */ |
| void config(IgniteConfiguration cfg) { |
| this.cfg = cfg; |
| } |
| |
| /** |
| * @return Optional configuration path. |
| */ |
| URL configUrl() { |
| return cfgUrl; |
| } |
| |
| /** |
| * @param cfgUrl Optional configuration path. |
| */ |
| void configUrl(URL cfgUrl) { |
| this.cfgUrl = cfgUrl; |
| } |
| |
| /** |
| * @return Optional Spring application context. |
| */ |
| public GridSpringResourceContext springContext() { |
| return springCtx; |
| } |
| } |
| |
| /** |
| * Grid data container. |
| */ |
| private static final class IgniteNamedInstance { |
| /** Map of registered MBeans. */ |
| private static final Map<MBeanServer, GridMBeanServerData> mbeans = |
| new HashMap<>(); |
| |
| /** */ |
| private static final String[] EMPTY_STR_ARR = new String[0]; |
| |
| /** Grid name. */ |
| private final String name; |
| |
| /** Grid instance. */ |
| private volatile IgniteKernal grid; |
| |
| /** Executor service. */ |
| private ThreadPoolExecutor execSvc; |
| |
| /** Executor service for services. */ |
| private ThreadPoolExecutor svcExecSvc; |
| |
| /** System executor service. */ |
| private ThreadPoolExecutor sysExecSvc; |
| |
| /** */ |
| private StripedExecutor stripedExecSvc; |
| |
| /** Management executor service. */ |
| private ThreadPoolExecutor mgmtExecSvc; |
| |
| /** P2P executor service. */ |
| private ThreadPoolExecutor p2pExecSvc; |
| |
| /** Data streamer executor service. */ |
| private StripedExecutor dataStreamerExecSvc; |
| |
| /** REST requests executor service. */ |
| private ThreadPoolExecutor restExecSvc; |
| |
| /** Utility cache executor service. */ |
| private ThreadPoolExecutor utilityCacheExecSvc; |
| |
| /** Affinity executor service. */ |
| private ThreadPoolExecutor affExecSvc; |
| |
| /** Indexing pool. */ |
| private ThreadPoolExecutor idxExecSvc; |
| |
| /** Thread pool for create/rebuild indexes. */ |
| private ThreadPoolExecutor buildIdxExecSvc; |
| |
| /** Continuous query executor service. */ |
| private IgniteStripedThreadPoolExecutor callbackExecSvc; |
| |
| /** Query executor service. */ |
| private ThreadPoolExecutor qryExecSvc; |
| |
| /** Query executor service. */ |
| private ThreadPoolExecutor schemaExecSvc; |
| |
| /** Rebalance executor service. */ |
| private ThreadPoolExecutor rebalanceExecSvc; |
| |
| /** Rebalance striped executor service. */ |
| private IgniteStripedThreadPoolExecutor rebalanceStripedExecSvc; |
| |
| /** Executor service. */ |
| private Map<String, ThreadPoolExecutor> customExecSvcs; |
| |
| /** Grid state. */ |
| private volatile IgniteState state = STOPPED; |
| |
| /** Shutdown hook. */ |
| private Thread shutdownHook; |
| |
| /** Grid log. */ |
| private IgniteLogger log; |
| |
| /** Start guard. */ |
| private final AtomicBoolean startGuard = new AtomicBoolean(); |
| |
| /** Start latch. */ |
| private final CountDownLatch startLatch = new CountDownLatch(1); |
| |
| /** Raised if node is waiting graceful shutdown. Set to false to end wait. */ |
| private volatile boolean delayedShutdown = false; |
| |
| /** |
| * Thread that starts this named instance. This field can be non-volatile since |
| * it makes sense only for thread where it was originally initialized. |
| */ |
| @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") |
| private Thread starterThread; |
| |
| /** */ |
| private boolean starterThreadInterrupted; |
| |
| /** |
| * Creates un-started named instance. |
| * |
| * @param name Grid name (possibly {@code null} for default grid). |
| */ |
| IgniteNamedInstance(@Nullable String name) { |
| this.name = name; |
| } |
| |
| /** |
| * Gets grid name. |
| * |
| * @return Grid name. |
| */ |
| String getName() { |
| return name; |
| } |
| |
| /** |
| * Gets grid instance. |
| * |
| * @return Grid instance. |
| */ |
| IgniteKernal grid() { |
| if (starterThread != Thread.currentThread()) |
| U.awaitQuiet(startLatch); |
| |
| return grid; |
| } |
| |
| /** |
| * Gets grid instance without waiting for its initialization. |
| * |
| * @return Grid instance. |
| */ |
| public IgniteKernal gridx() { |
| return grid; |
| } |
| |
| /** |
| * Gets grid state. |
| * |
| * @return Grid state. |
| */ |
| IgniteState state() { |
| if (starterThread != Thread.currentThread()) |
| U.awaitQuiet(startLatch); |
| |
| return state; |
| } |
| |
| /** |
| * @param spi SPI implementation. |
| * @throws IgniteCheckedException Thrown in case if multi-instance is not supported. |
| */ |
| private void ensureMultiInstanceSupport(IgniteSpi spi) throws IgniteCheckedException { |
| IgniteSpiMultipleInstancesSupport ann = U.getAnnotation(spi.getClass(), |
| IgniteSpiMultipleInstancesSupport.class); |
| |
| if (ann == null || !ann.value()) |
| throw new IgniteCheckedException("SPI implementation doesn't support multiple grid instances in " + |
| "the same VM: " + spi); |
| } |
| |
| /** |
| * @param spis SPI implementations. |
| * @throws IgniteCheckedException Thrown in case if multi-instance is not supported. |
| */ |
| private void ensureMultiInstanceSupport(IgniteSpi[] spis) throws IgniteCheckedException { |
| for (IgniteSpi spi : spis) |
| ensureMultiInstanceSupport(spi); |
| } |
| |
| /** |
| * Starts grid with given configuration. |
| * |
| * @param startCtx Starting context. |
| * @throws IgniteCheckedException If start failed. |
| */ |
| synchronized void start(GridStartContext startCtx) throws IgniteCheckedException { |
| if (startGuard.compareAndSet(false, true)) { |
| try { |
| starterThread = Thread.currentThread(); |
| |
| IgniteConfiguration myCfg = initializeConfiguration( |
| startCtx.config() != null ? startCtx.config() : new IgniteConfiguration() |
| ); |
| |
| TimeBag startNodeTimer = new TimeBag(TimeUnit.MILLISECONDS, log.isInfoEnabled()); |
| |
| start0(startCtx, myCfg, startNodeTimer); |
| |
| if (log.isInfoEnabled()) |
| log.info("Node started : " |
| + startNodeTimer.stagesTimings().stream().collect(joining(",", "[", "]"))); |
| } |
| catch (Exception e) { |
| if (log != null) |
| stopExecutors(log); |
| |
| throw e; |
| } |
| finally { |
| startLatch.countDown(); |
| } |
| } |
| else |
| U.awaitQuiet(startLatch); |
| } |
| |
| /** |
| * @param startCtx Starting context. |
| * @throws IgniteCheckedException If start failed. |
| */ |
| private void start0(GridStartContext startCtx, IgniteConfiguration cfg, TimeBag startTimer) |
| throws IgniteCheckedException { |
| assert grid == null : "Grid is already started: " + name; |
| |
| // Set configuration URL, if any, into system property. |
| if (startCtx.configUrl() != null) |
| System.setProperty(IGNITE_CONFIG_URL, startCtx.configUrl().toString()); |
| |
| // Ensure that SPIs support multiple grid instances, if required. |
| if (!startCtx.single()) { |
| ensureMultiInstanceSupport(cfg.getDeploymentSpi()); |
| ensureMultiInstanceSupport(cfg.getCommunicationSpi()); |
| ensureMultiInstanceSupport(cfg.getDiscoverySpi()); |
| ensureMultiInstanceSupport(cfg.getCheckpointSpi()); |
| ensureMultiInstanceSupport(cfg.getEventStorageSpi()); |
| ensureMultiInstanceSupport(cfg.getCollisionSpi()); |
| ensureMultiInstanceSupport(cfg.getFailoverSpi()); |
| ensureMultiInstanceSupport(cfg.getLoadBalancingSpi()); |
| } |
| |
| validateThreadPoolSize(cfg.getPublicThreadPoolSize(), "public"); |
| |
| UncaughtExceptionHandler oomeHnd = new UncaughtExceptionHandler() { |
| @Override public void uncaughtException(Thread t, Throwable e) { |
| if (grid != null && X.hasCause(e, OutOfMemoryError.class)) |
| grid.context().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); |
| } |
| }; |
| |
| UncaughtExceptionHandler excHnd = new UncaughtExceptionHandler() { |
| @Override public void uncaughtException(Thread t, Throwable e) { |
| if (grid != null) |
| grid.context().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); |
| } |
| }; |
| |
| execSvc = new IgniteThreadPoolExecutor( |
| "pub", |
| cfg.getIgniteInstanceName(), |
| cfg.getPublicThreadPoolSize(), |
| cfg.getPublicThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<Runnable>(), |
| GridIoPolicy.PUBLIC_POOL, |
| oomeHnd); |
| |
| execSvc.allowCoreThreadTimeOut(true); |
| |
| validateThreadPoolSize(cfg.getServiceThreadPoolSize(), "service"); |
| |
| svcExecSvc = new IgniteThreadPoolExecutor( |
| "svc", |
| cfg.getGridName(), |
| cfg.getServiceThreadPoolSize(), |
| cfg.getServiceThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<Runnable>(), |
| GridIoPolicy.SERVICE_POOL, |
| oomeHnd); |
| |
| svcExecSvc.allowCoreThreadTimeOut(true); |
| |
| validateThreadPoolSize(cfg.getSystemThreadPoolSize(), "system"); |
| |
| sysExecSvc = new IgniteThreadPoolExecutor( |
| "sys", |
| cfg.getIgniteInstanceName(), |
| cfg.getSystemThreadPoolSize(), |
| cfg.getSystemThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<Runnable>(), |
| GridIoPolicy.SYSTEM_POOL, |
| oomeHnd); |
| |
| sysExecSvc.allowCoreThreadTimeOut(true); |
| |
| validateThreadPoolSize(cfg.getStripedPoolSize(), "stripedPool"); |
| |
| WorkersRegistry workerRegistry = new WorkersRegistry( |
| new IgniteBiInClosure<GridWorker, FailureType>() { |
| @Override public void apply(GridWorker worker, FailureType failureType) { |
| IgniteException ex = new IgniteException(S.toString(GridWorker.class, worker)); |
| |
| Thread runner = worker.runner(); |
| |
| if (runner != null && runner != Thread.currentThread()) |
| ex.setStackTrace(runner.getStackTrace()); |
| |
| if (grid != null) |
| grid.context().failure().process(new FailureContext(failureType, ex)); |
| } |
| }, |
| IgniteSystemProperties.getLong(IGNITE_SYSTEM_WORKER_BLOCKED_TIMEOUT, |
| cfg.getSystemWorkerBlockedTimeout() != null |
| ? cfg.getSystemWorkerBlockedTimeout() |
| : cfg.getFailureDetectionTimeout()), |
| log); |
| |
| stripedExecSvc = new StripedExecutor( |
| cfg.getStripedPoolSize(), |
| cfg.getIgniteInstanceName(), |
| "sys", |
| log, |
| new IgniteInClosure<Throwable>() { |
| @Override public void apply(Throwable t) { |
| if (grid != null) |
| grid.context().failure().process(new FailureContext(SYSTEM_WORKER_TERMINATION, t)); |
| } |
| }, |
| workerRegistry, |
| cfg.getFailureDetectionTimeout()); |
| |
| // Note that since we use 'LinkedBlockingQueue', number of |
| // maximum threads has no effect. |
| // Note, that we do not pre-start threads here as management pool may |
| // not be needed. |
| validateThreadPoolSize(cfg.getManagementThreadPoolSize(), "management"); |
| |
| mgmtExecSvc = new IgniteThreadPoolExecutor( |
| "mgmt", |
| cfg.getIgniteInstanceName(), |
| cfg.getManagementThreadPoolSize(), |
| cfg.getManagementThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<Runnable>(), |
| GridIoPolicy.MANAGEMENT_POOL, |
| oomeHnd); |
| |
| mgmtExecSvc.allowCoreThreadTimeOut(true); |
| |
| // Note that since we use 'LinkedBlockingQueue', number of |
| // maximum threads has no effect. |
| // Note, that we do not pre-start threads here as class loading pool may |
| // not be needed. |
| validateThreadPoolSize(cfg.getPeerClassLoadingThreadPoolSize(), "peer class loading"); |
| |
| p2pExecSvc = new IgniteThreadPoolExecutor( |
| "p2p", |
| cfg.getIgniteInstanceName(), |
| cfg.getPeerClassLoadingThreadPoolSize(), |
| cfg.getPeerClassLoadingThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<Runnable>(), |
| GridIoPolicy.P2P_POOL, |
| oomeHnd); |
| |
| p2pExecSvc.allowCoreThreadTimeOut(true); |
| |
| dataStreamerExecSvc = new StripedExecutor( |
| cfg.getDataStreamerThreadPoolSize(), |
| cfg.getIgniteInstanceName(), |
| "data-streamer", |
| log, |
| new IgniteInClosure<Throwable>() { |
| @Override public void apply(Throwable t) { |
| if (grid != null) |
| grid.context().failure().process(new FailureContext(SYSTEM_WORKER_TERMINATION, t)); |
| } |
| }, |
| true, |
| workerRegistry, |
| cfg.getFailureDetectionTimeout()); |
| |
| // Note that we do not pre-start threads here as this pool may not be needed. |
| validateThreadPoolSize(cfg.getAsyncCallbackPoolSize(), "async callback"); |
| |
| callbackExecSvc = new IgniteStripedThreadPoolExecutor( |
| cfg.getAsyncCallbackPoolSize(), |
| cfg.getIgniteInstanceName(), |
| "callback", |
| oomeHnd, |
| false, |
| 0); |
| |
| if (cfg.getConnectorConfiguration() != null) { |
| validateThreadPoolSize(cfg.getConnectorConfiguration().getThreadPoolSize(), "connector"); |
| |
| restExecSvc = new IgniteThreadPoolExecutor( |
| "rest", |
| cfg.getIgniteInstanceName(), |
| cfg.getConnectorConfiguration().getThreadPoolSize(), |
| cfg.getConnectorConfiguration().getThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.UNDEFINED, |
| oomeHnd |
| ); |
| |
| restExecSvc.allowCoreThreadTimeOut(true); |
| } |
| |
| validateThreadPoolSize(cfg.getUtilityCacheThreadPoolSize(), "utility cache"); |
| |
| utilityCacheExecSvc = new IgniteThreadPoolExecutor( |
| "utility", |
| cfg.getIgniteInstanceName(), |
| cfg.getUtilityCacheThreadPoolSize(), |
| cfg.getUtilityCacheThreadPoolSize(), |
| cfg.getUtilityCacheKeepAliveTime(), |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.UTILITY_CACHE_POOL, |
| oomeHnd); |
| |
| utilityCacheExecSvc.allowCoreThreadTimeOut(true); |
| |
| affExecSvc = new IgniteThreadPoolExecutor( |
| "aff", |
| cfg.getIgniteInstanceName(), |
| 1, |
| 1, |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.AFFINITY_POOL, |
| oomeHnd); |
| |
| affExecSvc.allowCoreThreadTimeOut(true); |
| |
| if (IgniteComponentType.INDEXING.inClassPath()) { |
| int cpus = Runtime.getRuntime().availableProcessors(); |
| |
| idxExecSvc = new IgniteThreadPoolExecutor( |
| "idx", |
| cfg.getIgniteInstanceName(), |
| cpus, |
| cpus * 2, |
| 3000L, |
| new LinkedBlockingQueue<>(1000), |
| GridIoPolicy.IDX_POOL, |
| oomeHnd |
| ); |
| |
| int buildIdxThreadPoolSize = cfg.getBuildIndexThreadPoolSize(); |
| |
| validateThreadPoolSize(buildIdxThreadPoolSize, "build-idx"); |
| |
| buildIdxExecSvc = new IgniteThreadPoolExecutor( |
| "build-idx-runner", |
| cfg.getIgniteInstanceName(), |
| buildIdxThreadPoolSize, |
| buildIdxThreadPoolSize, |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.UNDEFINED, |
| oomeHnd |
| ); |
| |
| buildIdxExecSvc.allowCoreThreadTimeOut(true); |
| } |
| |
| validateThreadPoolSize(cfg.getQueryThreadPoolSize(), "query"); |
| |
| qryExecSvc = new IgniteThreadPoolExecutor( |
| "query", |
| cfg.getIgniteInstanceName(), |
| cfg.getQueryThreadPoolSize(), |
| cfg.getQueryThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.QUERY_POOL, |
| oomeHnd); |
| |
| qryExecSvc.allowCoreThreadTimeOut(true); |
| |
| schemaExecSvc = new IgniteThreadPoolExecutor( |
| "schema", |
| cfg.getIgniteInstanceName(), |
| 2, |
| 2, |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.SCHEMA_POOL, |
| oomeHnd); |
| |
| schemaExecSvc.allowCoreThreadTimeOut(true); |
| |
| validateThreadPoolSize(cfg.getRebalanceThreadPoolSize(), "rebalance"); |
| |
| rebalanceExecSvc = new IgniteThreadPoolExecutor( |
| "rebalance", |
| cfg.getIgniteInstanceName(), |
| cfg.getRebalanceThreadPoolSize(), |
| cfg.getRebalanceThreadPoolSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.UNDEFINED, |
| excHnd); |
| |
| rebalanceExecSvc.allowCoreThreadTimeOut(true); |
| |
| rebalanceStripedExecSvc = new IgniteStripedThreadPoolExecutor( |
| cfg.getRebalanceThreadPoolSize(), |
| cfg.getIgniteInstanceName(), |
| "rebalance-striped", |
| excHnd, |
| true, |
| DFLT_THREAD_KEEP_ALIVE_TIME); |
| |
| if (!F.isEmpty(cfg.getExecutorConfiguration())) { |
| validateCustomExecutorsConfiguration(cfg.getExecutorConfiguration()); |
| |
| customExecSvcs = new HashMap<>(); |
| |
| for (ExecutorConfiguration execCfg : cfg.getExecutorConfiguration()) { |
| ThreadPoolExecutor exec = new IgniteThreadPoolExecutor( |
| execCfg.getName(), |
| cfg.getIgniteInstanceName(), |
| execCfg.getSize(), |
| execCfg.getSize(), |
| DFLT_THREAD_KEEP_ALIVE_TIME, |
| new LinkedBlockingQueue<>(), |
| GridIoPolicy.UNDEFINED, |
| oomeHnd); |
| |
| customExecSvcs.put(execCfg.getName(), exec); |
| } |
| } |
| |
| // Register Ignite MBean for current grid instance. |
| registerFactoryMbean(cfg.getMBeanServer()); |
| |
| boolean started = false; |
| |
| try { |
| IgniteKernal grid0 = new IgniteKernal(startCtx.springContext()); |
| |
| // Init here to make grid available to lifecycle listeners. |
| grid = grid0; |
| |
| startTimer.finishGlobalStage("Configure system pool"); |
| |
| grid0.start( |
| cfg, |
| utilityCacheExecSvc, |
| execSvc, |
| svcExecSvc, |
| sysExecSvc, |
| stripedExecSvc, |
| p2pExecSvc, |
| mgmtExecSvc, |
| dataStreamerExecSvc, |
| restExecSvc, |
| affExecSvc, |
| idxExecSvc, |
| buildIdxExecSvc, |
| callbackExecSvc, |
| qryExecSvc, |
| schemaExecSvc, |
| rebalanceExecSvc, |
| rebalanceStripedExecSvc, |
| customExecSvcs, |
| new CA() { |
| @Override public void apply() { |
| startLatch.countDown(); |
| } |
| }, |
| workerRegistry, |
| oomeHnd, |
| startTimer |
| ); |
| |
| state = STARTED; |
| |
| if (log.isDebugEnabled()) |
| log.debug("Grid factory started ok: " + name); |
| |
| started = true; |
| } |
| catch (IgniteCheckedException e) { |
| unregisterFactoryMBean(); |
| |
| throw e; |
| } |
| // Catch Throwable to protect against any possible failure. |
| catch (Throwable e) { |
| unregisterFactoryMBean(); |
| |
| if (e instanceof Error) |
| throw e; |
| |
| throw new IgniteCheckedException("Unexpected exception when starting grid.", e); |
| } |
| finally { |
| if (!started) |
| // Grid was not started. |
| grid = null; |
| } |
| |
| // Do NOT set it up only if IGNITE_NO_SHUTDOWN_HOOK=TRUE is provided. |
| if (!IgniteSystemProperties.getBoolean(IGNITE_NO_SHUTDOWN_HOOK, false)) { |
| try { |
| Runtime.getRuntime().addShutdownHook(shutdownHook = new Thread("shutdown-hook") { |
| @Override public void run() { |
| if (log.isInfoEnabled()) |
| log.info("Invoking shutdown hook..."); |
| |
| IgniteNamedInstance ignite = IgniteNamedInstance.this; |
| |
| ignite.stop(true, null); |
| } |
| }); |
| |
| if (log.isDebugEnabled()) |
| log.debug("Shutdown hook is installed."); |
| } |
| catch (IllegalStateException e) { |
| stop(true, ShutdownPolicy.IMMEDIATE); |
| |
| throw new IgniteCheckedException("Failed to install shutdown hook.", e); |
| } |
| } |
| else { |
| if (log.isDebugEnabled()) |
| log.debug("Shutdown hook has not been installed because environment " + |
| "or system property " + IGNITE_NO_SHUTDOWN_HOOK + " is set."); |
| } |
| } |
| |
| /** |
| * @param poolSize an actual value in the configuration. |
| * @param poolName a name of the pool like 'management'. |
| * @throws IgniteCheckedException If the poolSize is wrong. |
| */ |
| private static void validateThreadPoolSize(int poolSize, String poolName) |
| throws IgniteCheckedException { |
| if (poolSize <= 0) { |
| throw new IgniteCheckedException("Invalid " + poolName + " thread pool size" + |
| " (must be greater than 0), actual value: " + poolSize); |
| } |
| } |
| |
| /** |
| * @param cfgs Array of the executors configurations. |
| * @throws IgniteCheckedException If configuration is wrong. |
| */ |
| private static void validateCustomExecutorsConfiguration(ExecutorConfiguration[] cfgs) |
| throws IgniteCheckedException { |
| if (cfgs == null) |
| return; |
| |
| Set<String> names = new HashSet<>(cfgs.length); |
| |
| for (ExecutorConfiguration cfg : cfgs) { |
| if (F.isEmpty(cfg.getName())) |
| throw new IgniteCheckedException("Custom executor name cannot be null or empty."); |
| |
| if (!names.add(cfg.getName())) |
| throw new IgniteCheckedException("Duplicate custom executor name: " + cfg.getName()); |
| |
| if (cfg.getSize() <= 0) |
| throw new IgniteCheckedException("Custom executor size must be positive [name=" + cfg.getName() + |
| ", size=" + cfg.getSize() + ']'); |
| } |
| } |
| |
| /** |
| * @param cfg Ignite configuration copy to. |
| * @return New ignite configuration. |
| * @throws IgniteCheckedException If failed. |
| */ |
| private IgniteConfiguration initializeConfiguration(IgniteConfiguration cfg) |
| throws IgniteCheckedException { |
| IgniteConfiguration myCfg = new IgniteConfiguration(cfg); |
| |
| String ggHome = cfg.getIgniteHome(); |
| |
| // Set Ignite home. |
| if (ggHome == null) |
| ggHome = U.getIgniteHome(); |
| else |
| // If user provided IGNITE_HOME - set it as a system property. |
| U.setIgniteHome(ggHome); |
| |
| String userProvidedWorkDir = cfg.getWorkDirectory(); |
| |
| // Correctly resolve work directory and set it back to configuration. |
| String workDir = U.workDirectory(userProvidedWorkDir, ggHome); |
| |
| myCfg.setWorkDirectory(workDir); |
| |
| // Ensure invariant. |
| // It's a bit dirty - but this is a result of late refactoring |
| // and I don't want to reshuffle a lot of code. |
| assert F.eq(name, cfg.getIgniteInstanceName()); |
| |
| UUID nodeId = cfg.getNodeId() != null ? cfg.getNodeId() : UUID.randomUUID(); |
| |
| myCfg.setNodeId(nodeId); |
| |
| String predefineConsistentId = IgniteSystemProperties.getString(IGNITE_OVERRIDE_CONSISTENT_ID); |
| |
| if (!F.isEmpty(predefineConsistentId)) |
| myCfg.setConsistentId(predefineConsistentId); |
| |
| IgniteLogger cfgLog = initLogger(cfg.getGridLogger(), nodeId, workDir); |
| |
| assert cfgLog != null; |
| |
| cfgLog = new GridLoggerProxy(cfgLog, null, name, U.id8(nodeId)); |
| |
| // Initialize factory's log. |
| log = cfgLog.getLogger(G.class); |
| |
| myCfg.setGridLogger(cfgLog); |
| |
| if (F.isEmpty(userProvidedWorkDir) && F.isEmpty(U.IGNITE_WORK_DIR)) |
| log.warning("Ignite work directory is not provided, automatically resolved to: " + workDir); |
| |
| // Check Ignite home folder (after log is available). |
| if (ggHome != null) { |
| File ggHomeFile = new File(ggHome); |
| |
| if (!ggHomeFile.exists() || !ggHomeFile.isDirectory()) |
| throw new IgniteCheckedException("Invalid Ignite installation home folder: " + ggHome); |
| } |
| |
| myCfg.setIgniteHome(ggHome); |
| |
| // Validate segmentation configuration. |
| SegmentationPolicy segPlc = cfg.getSegmentationPolicy(); |
| |
| // 1. Warn on potential configuration problem: grid is not configured to wait |
| // for correct segment after segmentation happens. |
| if (!F.isEmpty(cfg.getSegmentationResolvers()) && segPlc == RESTART_JVM && !cfg.isWaitForSegmentOnStart()) { |
| U.warn(log, "Found potential configuration problem (forgot to enable waiting for segment" + |
| "on start?) [segPlc=" + segPlc + ", wait=false]"); |
| } |
| |
| if (CU.isPersistenceEnabled(cfg) && myCfg.getConsistentId() == null) |
| U.warn(log, "Consistent ID is not set, it is recommended to set consistent ID for production " + |
| "clusters (use IgniteConfiguration.setConsistentId property)"); |
| |
| myCfg.setTransactionConfiguration(myCfg.getTransactionConfiguration() != null ? |
| new TransactionConfiguration(myCfg.getTransactionConfiguration()) : null); |
| |
| myCfg.setConnectorConfiguration(myCfg.getConnectorConfiguration() != null ? |
| new ConnectorConfiguration(myCfg.getConnectorConfiguration()) : null); |
| |
| // Local host. |
| String locHost = IgniteSystemProperties.getString(IGNITE_LOCAL_HOST); |
| |
| myCfg.setLocalHost(F.isEmpty(locHost) ? myCfg.getLocalHost() : locHost); |
| |
| // Override daemon flag if it was set on the factory. |
| if (daemon.get()) |
| myCfg.setDaemon(true); |
| |
| if (myCfg.isClientMode() == null) { |
| Boolean threadClient = clientMode.get(); |
| |
| if (threadClient == null) |
| myCfg.setClientMode(IgniteSystemProperties.getBoolean(IGNITE_CACHE_CLIENT, false)); |
| else |
| myCfg.setClientMode(threadClient); |
| } |
| |
| // Check for deployment mode override. |
| String depModeName = IgniteSystemProperties.getString(IGNITE_DEP_MODE_OVERRIDE); |
| |
| if (!F.isEmpty(depModeName)) { |
| if (!F.isEmpty(myCfg.getCacheConfiguration())) { |
| U.quietAndInfo(log, "Skipping deployment mode override for caches (custom closure " + |
| "execution may not work for console Visor)"); |
| } |
| else { |
| try { |
| DeploymentMode depMode = DeploymentMode.valueOf(depModeName); |
| |
| if (myCfg.getDeploymentMode() != depMode) |
| myCfg.setDeploymentMode(depMode); |
| } |
| catch (IllegalArgumentException e) { |
| throw new IgniteCheckedException("Failed to override deployment mode using system property " + |
| "(are there any misspellings?)" + |
| "[name=" + IGNITE_DEP_MODE_OVERRIDE + ", value=" + depModeName + ']', e); |
| } |
| } |
| } |
| |
| if (myCfg.getUserAttributes() == null) |
| myCfg.setUserAttributes(Collections.<String, Object>emptyMap()); |
| |
| if (myCfg.getMBeanServer() == null && !U.IGNITE_MBEANS_DISABLED) |
| myCfg.setMBeanServer(ManagementFactory.getPlatformMBeanServer()); |
| |
| Marshaller marsh = myCfg.getMarshaller(); |
| |
| if (marsh == null) { |
| if (!BinaryMarshaller.available()) { |
| U.warn(log, "Standard BinaryMarshaller can't be used on this JVM. " + |
| "Switch to HotSpot JVM or reach out Apache Ignite community for recommendations."); |
| |
| marsh = new JdkMarshaller(); |
| } |
| else |
| marsh = new BinaryMarshaller(); |
| } |
| |
| MarshallerUtils.setNodeName(marsh, cfg.getIgniteInstanceName()); |
| |
| myCfg.setMarshaller(marsh); |
| |
| if (myCfg.getPeerClassLoadingLocalClassPathExclude() == null) |
| myCfg.setPeerClassLoadingLocalClassPathExclude(EMPTY_STR_ARR); |
| |
| initializeDefaultSpi(myCfg); |
| |
| GridDiscoveryManager.initCommunicationErrorResolveConfiguration(myCfg); |
| |
| initializeDefaultCacheConfiguration(myCfg); |
| |
| ExecutorConfiguration[] execCfgs = myCfg.getExecutorConfiguration(); |
| |
| if (execCfgs != null) { |
| ExecutorConfiguration[] clone = execCfgs.clone(); |
| |
| for (int i = 0; i < execCfgs.length; i++) |
| clone[i] = new ExecutorConfiguration(execCfgs[i]); |
| |
| myCfg.setExecutorConfiguration(clone); |
| } |
| |
| initializeDataStorageConfiguration(myCfg); |
| |
| return myCfg; |
| } |
| |
| /** |
| * @param cfg Ignite configuration. |
| */ |
| private void initializeDataStorageConfiguration(IgniteConfiguration cfg) throws IgniteCheckedException { |
| if (cfg.getDataStorageConfiguration() != null && |
| (cfg.getMemoryConfiguration() != null || cfg.getPersistentStoreConfiguration() != null)) { |
| throw new IgniteCheckedException("Data storage can be configured with either legacy " + |
| "(MemoryConfiguration, PersistentStoreConfiguration) or new (DataStorageConfiguration) classes, " + |
| "but not both."); |
| } |
| |
| if (cfg.getMemoryConfiguration() != null || cfg.getPersistentStoreConfiguration() != null) |
| convertLegacyDataStorageConfigurationToNew(cfg); |
| |
| if (!cfg.isClientMode() && cfg.getDataStorageConfiguration() == null) |
| cfg.setDataStorageConfiguration(new DataStorageConfiguration()); |
| } |
| |
| /** |
| * Initialize default cache configuration. |
| * |
| * @param cfg Ignite configuration. |
| * @throws IgniteCheckedException If failed. |
| */ |
| public void initializeDefaultCacheConfiguration(IgniteConfiguration cfg) throws IgniteCheckedException { |
| List<CacheConfiguration> cacheCfgs = new ArrayList<>(); |
| |
| cacheCfgs.add(utilitySystemCache()); |
| |
| CacheConfiguration[] userCaches = cfg.getCacheConfiguration(); |
| |
| if (userCaches != null && userCaches.length > 0) { |
| if (!U.discoOrdered(cfg.getDiscoverySpi()) && !U.relaxDiscoveryOrdered()) |
| throw new IgniteCheckedException("Discovery SPI implementation does not support node ordering and " + |
| "cannot be used with cache (use SPI with @DiscoverySpiOrderSupport annotation, " + |
| "like TcpDiscoverySpi)"); |
| |
| for (CacheConfiguration ccfg : userCaches) { |
| if (CU.isReservedCacheName(ccfg.getName())) |
| throw new IgniteCheckedException("Cache name cannot be \"" + ccfg.getName() + |
| "\" because it is reserved for internal purposes."); |
| |
| if (DataStructuresProcessor.isDataStructureCache(ccfg.getName())) |
| throw new IgniteCheckedException("Cache name cannot be \"" + ccfg.getName() + |
| "\" because it is reserved for data structures."); |
| |
| cacheCfgs.add(ccfg); |
| } |
| } |
| |
| cfg.setCacheConfiguration(cacheCfgs.toArray(new CacheConfiguration[cacheCfgs.size()])); |
| |
| assert cfg.getCacheConfiguration() != null; |
| } |
| |
| /** |
| * Initialize default SPI implementations. |
| * |
| * @param cfg Ignite configuration. |
| */ |
| private void initializeDefaultSpi(IgniteConfiguration cfg) { |
| if (cfg.getDiscoverySpi() == null) |
| cfg.setDiscoverySpi(new TcpDiscoverySpi()); |
| |
| if (cfg.getDiscoverySpi() instanceof TcpDiscoverySpi) { |
| TcpDiscoverySpi tcpDisco = (TcpDiscoverySpi)cfg.getDiscoverySpi(); |
| |
| if (tcpDisco.getIpFinder() == null) |
| tcpDisco.setIpFinder(new TcpDiscoveryMulticastIpFinder()); |
| } |
| |
| if (cfg.getCommunicationSpi() == null) |
| cfg.setCommunicationSpi(new TcpCommunicationSpi()); |
| |
| if (cfg.getDeploymentSpi() == null) |
| cfg.setDeploymentSpi(new LocalDeploymentSpi()); |
| |
| if (cfg.getEventStorageSpi() == null) |
| cfg.setEventStorageSpi(new NoopEventStorageSpi()); |
| |
| if (cfg.getCheckpointSpi() == null) |
| cfg.setCheckpointSpi(new NoopCheckpointSpi()); |
| |
| if (cfg.getCollisionSpi() == null) |
| cfg.setCollisionSpi(new NoopCollisionSpi()); |
| |
| if (cfg.getFailoverSpi() == null) |
| cfg.setFailoverSpi(new AlwaysFailoverSpi()); |
| |
| if (cfg.getLoadBalancingSpi() == null) |
| cfg.setLoadBalancingSpi(new RoundRobinLoadBalancingSpi()); |
| else { |
| Collection<LoadBalancingSpi> spis = new ArrayList<>(); |
| |
| boolean dfltLoadBalancingSpi = false; |
| |
| for (LoadBalancingSpi spi : cfg.getLoadBalancingSpi()) { |
| spis.add(spi); |
| |
| if (!dfltLoadBalancingSpi && spi instanceof RoundRobinLoadBalancingSpi) |
| dfltLoadBalancingSpi = true; |
| } |
| |
| // Add default load balancing SPI for internal tasks. |
| if (!dfltLoadBalancingSpi) |
| spis.add(new RoundRobinLoadBalancingSpi()); |
| |
| cfg.setLoadBalancingSpi(spis.toArray(new LoadBalancingSpi[spis.size()])); |
| } |
| |
| if (cfg.getIndexingSpi() == null) |
| cfg.setIndexingSpi(new NoopIndexingSpi()); |
| |
| if (cfg.getEncryptionSpi() == null) |
| cfg.setEncryptionSpi(new NoopEncryptionSpi()); |
| |
| if (F.isEmpty(cfg.getMetricExporterSpi())) |
| cfg.setMetricExporterSpi(new NoopMetricExporterSpi()); |
| |
| if (cfg.getTracingSpi() == null) |
| cfg.setTracingSpi(new NoopTracingSpi()); |
| } |
| |
| /** |
| * @param cfgLog Configured logger. |
| * @param nodeId Local node ID. |
| * @param workDir Work directory. |
| * @return Initialized logger. |
| * @throws IgniteCheckedException If failed. |
| */ |
| @SuppressWarnings("ErrorNotRethrown") |
| private IgniteLogger initLogger(@Nullable IgniteLogger cfgLog, UUID nodeId, String workDir) |
| throws IgniteCheckedException { |
| try { |
| Exception log4jInitErr = null; |
| |
| if (cfgLog == null) { |
| Class<?> log4jCls; |
| |
| try { |
| log4jCls = Class.forName("org.apache.ignite.logger.log4j.Log4JLogger"); |
| } |
| catch (ClassNotFoundException | NoClassDefFoundError ignored) { |
| log4jCls = null; |
| } |
| |
| if (log4jCls != null) { |
| try { |
| URL url = U.resolveIgniteUrl("config/ignite-log4j.xml"); |
| |
| if (url == null) { |
| File cfgFile = new File("config/ignite-log4j.xml"); |
| |
| if (!cfgFile.exists()) |
| cfgFile = new File("../config/ignite-log4j.xml"); |
| |
| if (cfgFile.exists()) { |
| try { |
| url = cfgFile.toURI().toURL(); |
| } |
| catch (MalformedURLException ignore) { |
| // No-op. |
| } |
| } |
| } |
| |
| if (url != null) { |
| boolean configured = (Boolean)log4jCls.getMethod("isConfigured").invoke(null); |
| |
| if (configured) |
| url = null; |
| } |
| |
| if (url != null) { |
| Constructor<?> ctor = log4jCls.getConstructor(URL.class); |
| |
| cfgLog = (IgniteLogger)ctor.newInstance(url); |
| } |
| else |
| cfgLog = (IgniteLogger)log4jCls.newInstance(); |
| } |
| catch (Exception e) { |
| log4jInitErr = e; |
| } |
| } |
| |
| if (log4jCls == null || log4jInitErr != null) |
| cfgLog = new JavaLogger(); |
| } |
| |
| // Special handling for Java logger which requires work directory. |
| if (cfgLog instanceof JavaLogger) |
| ((JavaLogger)cfgLog).setWorkDirectory(workDir); |
| |
| // Set node IDs for all file appenders. |
| if (cfgLog instanceof LoggerNodeIdAware) |
| ((LoggerNodeIdAware)cfgLog).setNodeId(nodeId); |
| |
| if (log4jInitErr != null) |
| U.warn(cfgLog, "Failed to initialize Log4JLogger (falling back to standard java logging): " |
| + log4jInitErr.getCause()); |
| |
| return cfgLog; |
| } |
| catch (Exception e) { |
| throw new IgniteCheckedException("Failed to create logger.", e); |
| } |
| } |
| |
| /** |
| * Creates utility system cache configuration. |
| * |
| * @return Utility system cache configuration. |
| */ |
| private static CacheConfiguration utilitySystemCache() { |
| CacheConfiguration cache = new CacheConfiguration(); |
| |
| cache.setName(CU.UTILITY_CACHE_NAME); |
| cache.setCacheMode(REPLICATED); |
| cache.setAtomicityMode(TRANSACTIONAL); |
| cache.setRebalanceMode(SYNC); |
| cache.setWriteSynchronizationMode(FULL_SYNC); |
| cache.setAffinity(new RendezvousAffinityFunction(false, 100)); |
| cache.setNodeFilter(CacheConfiguration.ALL_NODES); |
| cache.setRebalanceOrder(-2); //Prior to user caches. |
| cache.setCopyOnRead(false); |
| |
| return cache; |
| } |
| |
| /** |
| * Stops grid. |
| * |
| * @param cancel Flag indicating whether all currently running jobs |
| * should be cancelled. |
| * @param shutdown This is a policy of shutdown which is applied forcibly. |
| * If this property is {@code null}, present policy of the cluster will be used. |
| */ |
| void stop(boolean cancel, ShutdownPolicy shutdown) { |
| // Stop cannot be called prior to start from public API, |
| // since it checks for STARTED state. So, we can assert here. |
| assert startGuard.get(); |
| |
| if (shutdown == null) |
| shutdown = determineShutdownPolicy(); |
| |
| // If waiting for backups due to earlier invocation of stop(), stop wait and proceed shutting down. |
| if (shutdown == ShutdownPolicy.IMMEDIATE) |
| delayedShutdown = false; |
| |
| stop0(cancel, shutdown); |
| } |
| |
| /** |
| * Reads a policy from distributed meta storage or returns a default value if it isn't present. |
| * |
| * @return Shutdown policy. |
| */ |
| private ShutdownPolicy determineShutdownPolicy() { |
| if (IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_WAIT_FOR_BACKUPS_ON_SHUTDOWN)) |
| return ShutdownPolicy.GRACEFUL; |
| |
| return grid.cluster().shutdownPolicy(); |
| } |
| |
| /** |
| * Stops instance synchronously according to parameters. |
| * |
| * @param cancel Flag indicating whether all currently running job |
| * should be cancelled. |
| * @param shutdown Policy according to which shutdown will be performed. |
| */ |
| 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().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.isLocal() || 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()) { |
| Set<UUID> supportedPolicyNodes = proposedSuppliers.keySet().stream() |
| .filter(nodeId -> |
| IgniteFeatures.nodeSupports(grid0.cluster().node(nodeId), IgniteFeatures.SHUTDOWN_POLICY)) |
| .collect(Collectors.toSet()); |
| |
| if (!supportedPolicyNodes.isEmpty()) { |
| safeToStop = grid0.compute(grid0.cluster().forNodeIds(supportedPolicyNodes)) |
| .execute(CheckCpHistTask.class, proposedSuppliers); |
| } |
| } |
| |
| if (safeToStop) { |
| try { |
| HashSet<UUID> newNodesToExclude = new HashSet<>(nodesToExclude); |
| newNodesToExclude.add(grid.getLocalNodeId()); |
| |
| 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; |
| |
| if (log != null) |
| stopExecutors(log); |
| |
| log = null; |
| } |
| } |
| |
| /** |
| * Checks, does the cluster have another copy of each local partition for specific group. |
| * Also, the method collects all nodes with can supply a local partition into {@code proposedSuppliers}. |
| * |
| * @param grpCtx Cahce group. |
| * @param nodesToExclude Nodes to exclude from check. |
| * @param proposedSuppliers Map of proposed suppliers for groups. |
| * @return True if all local partition of group specified have a copy in cluster, false otherwise. |
| */ |
| private boolean haveCopyLocalPartitions( |
| CacheGroupContext grpCtx, |
| Set<UUID> nodesToExclude, |
| Map<UUID, Map<Integer, Set<Integer>>> proposedSuppliers |
| ) { |
| GridDhtPartitionFullMap fullMap = grpCtx.topology().partitionMap(false); |
| |
| if (fullMap == null) |
| return false; |
| |
| UUID localNodeId = grid.getLocalNodeId(); |
| |
| GridDhtPartitionMap localPartMap = fullMap.get(localNodeId); |
| |
| int parts = grpCtx.topology().partitions(); |
| |
| List<List<ClusterNode>> idealAssignment = grpCtx.affinity().idealAssignmentRaw(); |
| |
| for (int p = 0; p < parts; p++) { |
| if (localPartMap.get(p) != GridDhtPartitionState.OWNING) |
| continue; |
| |
| boolean foundCopy = false; |
| |
| for (Map.Entry<UUID, GridDhtPartitionMap> entry : fullMap.entrySet()) { |
| if (localNodeId.equals(entry.getKey()) || nodesToExclude.contains(entry.getKey())) |
| continue; |
| |
| //This remote node does not present in ideal assignment. |
| if (!idealAssignment.get(p).stream().anyMatch(node -> node.id().equals(entry.getKey()))) |
| continue; |
| |
| //Rebalance in this cache. |
| if (entry.getValue().hasMovingPartitions()) |
| continue; |
| |
| if (entry.getValue().get(p) == GridDhtPartitionState.OWNING) { |
| proposedSuppliers.computeIfAbsent(entry.getKey(), (nodeId) -> new HashMap<>()) |
| .computeIfAbsent(grpCtx.groupId(), grpId -> new HashSet<>()) |
| .add(p); |
| |
| foundCopy = true; |
| } |
| } |
| |
| if (!foundCopy) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Check is rebalance completed for specific group on this node or not. |
| * It checks Demander and Supplier contexts. |
| * |
| * @param grpCtx Group context. |
| * @return True if rebalance completed, false otherwise. |
| */ |
| private boolean isRebalanceCompleted(CacheGroupContext grpCtx) { |
| if (!grpCtx.preloader().rebalanceFuture().isDone()) |
| return false; |
| |
| grpCtx.preloader().pause(); |
| |
| try { |
| return !((GridDhtPreloader)grpCtx.preloader()).supplier().isSupply(); |
| } |
| finally { |
| grpCtx.preloader().resume(); |
| } |
| } |
| |
| /** |
| * Stops executor services if they has been started. |
| * |
| * @param log Grid logger. |
| */ |
| private void stopExecutors(IgniteLogger log) { |
| boolean interrupted = Thread.interrupted(); |
| |
| try { |
| stopExecutors0(log); |
| } |
| finally { |
| if (interrupted) |
| Thread.currentThread().interrupt(); |
| } |
| } |
| |
| /** |
| * Stops executor services if they has been started. |
| * |
| * @param log Grid logger. |
| */ |
| private void stopExecutors0(IgniteLogger log) { |
| assert log != null; |
| |
| U.shutdownNow(getClass(), execSvc, log); |
| |
| execSvc = null; |
| |
| U.shutdownNow(getClass(), svcExecSvc, log); |
| |
| svcExecSvc = null; |
| |
| U.shutdownNow(getClass(), sysExecSvc, log); |
| |
| sysExecSvc = null; |
| |
| U.shutdownNow(getClass(), qryExecSvc, log); |
| |
| qryExecSvc = null; |
| |
| U.shutdownNow(getClass(), schemaExecSvc, log); |
| |
| schemaExecSvc = null; |
| |
| U.shutdownNow(getClass(), rebalanceExecSvc, log); |
| |
| rebalanceExecSvc = null; |
| |
| U.shutdownNow(getClass(), rebalanceStripedExecSvc, log); |
| |
| rebalanceStripedExecSvc = null; |
| |
| U.shutdownNow(getClass(), stripedExecSvc, log); |
| |
| stripedExecSvc = null; |
| |
| U.shutdownNow(getClass(), mgmtExecSvc, log); |
| |
| mgmtExecSvc = null; |
| |
| U.shutdownNow(getClass(), p2pExecSvc, log); |
| |
| p2pExecSvc = null; |
| |
| U.shutdownNow(getClass(), dataStreamerExecSvc, log); |
| |
| dataStreamerExecSvc = null; |
| |
| if (restExecSvc != null) |
| U.shutdownNow(getClass(), restExecSvc, log); |
| |
| restExecSvc = null; |
| |
| U.shutdownNow(getClass(), utilityCacheExecSvc, log); |
| |
| utilityCacheExecSvc = null; |
| |
| U.shutdownNow(getClass(), affExecSvc, log); |
| |
| affExecSvc = null; |
| |
| U.shutdownNow(getClass(), idxExecSvc, log); |
| |
| idxExecSvc = null; |
| |
| U.shutdownNow(getClass(), buildIdxExecSvc, log); |
| |
| buildIdxExecSvc = null; |
| |
| U.shutdownNow(getClass(), callbackExecSvc, log); |
| |
| callbackExecSvc = null; |
| |
| if (!F.isEmpty(customExecSvcs)) { |
| for (ThreadPoolExecutor exec : customExecSvcs.values()) |
| U.shutdownNow(getClass(), exec, log); |
| |
| customExecSvcs = null; |
| } |
| } |
| |
| /** |
| * Registers delegate Mbean instance for {@link Ignition}. |
| * |
| * @param srv MBeanServer where mbean should be registered. |
| * @throws IgniteCheckedException If registration failed. |
| */ |
| private void registerFactoryMbean(MBeanServer srv) throws IgniteCheckedException { |
| if (U.IGNITE_MBEANS_DISABLED) |
| return; |
| |
| assert srv != null; |
| |
| synchronized (mbeans) { |
| GridMBeanServerData data = mbeans.get(srv); |
| |
| if (data == null) { |
| try { |
| IgnitionMXBean mbean = new IgnitionMXBeanAdapter(); |
| |
| ObjectName objName = U.makeMBeanName( |
| null, |
| "Kernal", |
| Ignition.class.getSimpleName() |
| ); |
| |
| // Make check if MBean was already registered. |
| if (!srv.queryMBeans(objName, null).isEmpty()) |
| throw new IgniteCheckedException("MBean was already registered: " + objName); |
| else { |
| objName = U.registerMBean( |
| srv, |
| null, |
| "Kernal", |
| Ignition.class.getSimpleName(), |
| mbean, |
| IgnitionMXBean.class |
| ); |
| |
| data = new GridMBeanServerData(objName); |
| |
| mbeans.put(srv, data); |
| |
| if (log.isDebugEnabled()) |
| log.debug("Registered MBean: " + objName); |
| } |
| } |
| catch (JMException e) { |
| throw new IgniteCheckedException("Failed to register MBean.", e); |
| } |
| } |
| |
| assert data != null; |
| |
| data.addIgniteInstance(name); |
| data.setCounter(data.getCounter() + 1); |
| } |
| } |
| |
| /** |
| * Unregister delegate Mbean instance for {@link Ignition}. |
| */ |
| private void unregisterFactoryMBean() { |
| if (U.IGNITE_MBEANS_DISABLED) |
| return; |
| |
| synchronized (mbeans) { |
| Iterator<Entry<MBeanServer, GridMBeanServerData>> iter = mbeans.entrySet().iterator(); |
| |
| while (iter.hasNext()) { |
| Entry<MBeanServer, GridMBeanServerData> entry = iter.next(); |
| |
| if (entry.getValue().containsIgniteInstance(name)) { |
| GridMBeanServerData data = entry.getValue(); |
| |
| assert data != null; |
| |
| // Unregister MBean if no grid instances started for current MBeanServer. |
| if (data.getCounter() == 1) { |
| try { |
| entry.getKey().unregisterMBean(data.getMbean()); |
| |
| if (log.isDebugEnabled()) |
| log.debug("Unregistered MBean: " + data.getMbean()); |
| } |
| catch (JMException e) { |
| U.error(log, "Failed to unregister MBean.", e); |
| } |
| |
| iter.remove(); |
| } |
| else { |
| // Decrement counter. |
| data.setCounter(data.getCounter() - 1); |
| data.removeIgniteInstance(name); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Grid factory MBean data container. |
| * Contains necessary data for selected MBeanServer. |
| */ |
| private static class GridMBeanServerData { |
| /** Set of grid names for selected MBeanServer. */ |
| private Collection<String> igniteInstanceNames = new HashSet<>(); |
| |
| /** */ |
| private ObjectName mbean; |
| |
| /** Count of grid instances. */ |
| private int cnt; |
| |
| /** |
| * Create data container. |
| * |
| * @param mbean Object name of MBean. |
| */ |
| GridMBeanServerData(ObjectName mbean) { |
| assert mbean != null; |
| |
| this.mbean = mbean; |
| } |
| |
| /** |
| * Add Ignite instance name. |
| * |
| * @param igniteInstanceName Ignite instance name. |
| */ |
| public void addIgniteInstance(String igniteInstanceName) { |
| igniteInstanceNames.add(igniteInstanceName); |
| } |
| |
| /** |
| * Remove Ignite instance name. |
| * |
| * @param igniteInstanceName Ignite instance name. |
| */ |
| public void removeIgniteInstance(String igniteInstanceName) { |
| igniteInstanceNames.remove(igniteInstanceName); |
| } |
| |
| /** |
| * Returns {@code true} if data contains the specified |
| * Ignite instance name. |
| * |
| * @param igniteInstanceName Ignite instance name. |
| * @return {@code true} if data contains the specified Ignite instance name. |
| */ |
| public boolean containsIgniteInstance(String igniteInstanceName) { |
| return igniteInstanceNames.contains(igniteInstanceName); |
| } |
| |
| /** |
| * Gets name used in MBean server. |
| * |
| * @return Object name of MBean. |
| */ |
| public ObjectName getMbean() { |
| return mbean; |
| } |
| |
| /** |
| * Gets number of grid instances working with MBeanServer. |
| * |
| * @return Number of grid instances. |
| */ |
| public int getCounter() { |
| return cnt; |
| } |
| |
| /** |
| * Sets number of grid instances working with MBeanServer. |
| * |
| * @param cnt Number of grid instances. |
| */ |
| public void setCounter(int cnt) { |
| this.cnt = cnt; |
| } |
| } |
| |
| /** |
| * @return whether the startLatch has been counted down, thereby indicating that the kernal has full started. |
| */ |
| public boolean hasStartLatchCompleted() { |
| return startLatch.getCount() == 0; |
| } |
| } |
| |
| /** |
| * @param cfg Ignite Configuration with legacy data storage configuration. |
| */ |
| private static void convertLegacyDataStorageConfigurationToNew( |
| IgniteConfiguration cfg) throws IgniteCheckedException { |
| PersistentStoreConfiguration psCfg = cfg.getPersistentStoreConfiguration(); |
| |
| boolean persistenceEnabled = psCfg != null; |
| |
| DataStorageConfiguration dsCfg = new DataStorageConfiguration(); |
| |
| MemoryConfiguration memCfg = cfg.getMemoryConfiguration() != null ? |
| cfg.getMemoryConfiguration() : new MemoryConfiguration(); |
| |
| dsCfg.setConcurrencyLevel(memCfg.getConcurrencyLevel()); |
| dsCfg.setPageSize(memCfg.getPageSize()); |
| dsCfg.setSystemRegionInitialSize(memCfg.getSystemCacheInitialSize()); |
| dsCfg.setSystemRegionMaxSize(memCfg.getSystemCacheMaxSize()); |
| |
| List<DataRegionConfiguration> optionalDataRegions = new ArrayList<>(); |
| |
| boolean customDfltPlc = false; |
| |
| if (memCfg.getMemoryPolicies() != null) { |
| for (MemoryPolicyConfiguration mpc : memCfg.getMemoryPolicies()) { |
| DataRegionConfiguration region = new DataRegionConfiguration(); |
| |
| region.setPersistenceEnabled(persistenceEnabled); |
| |
| if (mpc.getInitialSize() != 0L) |
| region.setInitialSize(mpc.getInitialSize()); |
| |
| region.setEmptyPagesPoolSize(mpc.getEmptyPagesPoolSize()); |
| region.setEvictionThreshold(mpc.getEvictionThreshold()); |
| region.setMaxSize(mpc.getMaxSize()); |
| region.setName(mpc.getName()); |
| region.setPageEvictionMode(mpc.getPageEvictionMode()); |
| region.setMetricsRateTimeInterval(mpc.getRateTimeInterval()); |
| region.setMetricsSubIntervalCount(mpc.getSubIntervals()); |
| region.setSwapPath(mpc.getSwapFilePath()); |
| region.setMetricsEnabled(mpc.isMetricsEnabled()); |
| |
| if (persistenceEnabled) |
| region.setCheckpointPageBufferSize(psCfg.getCheckpointingPageBufferSize()); |
| |
| if (mpc.getName() == null) { |
| throw new IgniteCheckedException(new IllegalArgumentException( |
| "User-defined MemoryPolicyConfiguration must have non-null and non-empty name.")); |
| } |
| |
| if (mpc.getName().equals(memCfg.getDefaultMemoryPolicyName())) { |
| customDfltPlc = true; |
| |
| dsCfg.setDefaultDataRegionConfiguration(region); |
| } else |
| optionalDataRegions.add(region); |
| } |
| } |
| |
| if (!optionalDataRegions.isEmpty()) |
| dsCfg.setDataRegionConfigurations(optionalDataRegions.toArray( |
| new DataRegionConfiguration[optionalDataRegions.size()])); |
| |
| if (!customDfltPlc) { |
| if (!DFLT_MEM_PLC_DEFAULT_NAME.equals(memCfg.getDefaultMemoryPolicyName())) { |
| throw new IgniteCheckedException(new IllegalArgumentException("User-defined default MemoryPolicy " + |
| "name must be presented among configured MemoryPolices: " + memCfg.getDefaultMemoryPolicyName())); |
| } |
| |
| dsCfg.setDefaultDataRegionConfiguration(new DataRegionConfiguration() |
| .setMaxSize(memCfg.getDefaultMemoryPolicySize()) |
| .setName(memCfg.getDefaultMemoryPolicyName()) |
| .setPersistenceEnabled(persistenceEnabled)); |
| } else { |
| if (memCfg.getDefaultMemoryPolicySize() != DFLT_MEMORY_POLICY_MAX_SIZE) |
| throw new IgniteCheckedException(new IllegalArgumentException("User-defined MemoryPolicy " + |
| "configuration and defaultMemoryPolicySize properties are set at the same time.")); |
| } |
| |
| if (persistenceEnabled) { |
| dsCfg.setCheckpointFrequency(psCfg.getCheckpointingFrequency()); |
| dsCfg.setCheckpointThreads(psCfg.getCheckpointingThreads()); |
| dsCfg.setCheckpointWriteOrder(psCfg.getCheckpointWriteOrder()); |
| dsCfg.setFileIOFactory(psCfg.getFileIOFactory()); |
| dsCfg.setLockWaitTime(psCfg.getLockWaitTime()); |
| dsCfg.setStoragePath(psCfg.getPersistentStorePath()); |
| dsCfg.setMetricsRateTimeInterval(psCfg.getRateTimeInterval()); |
| dsCfg.setMetricsSubIntervalCount(psCfg.getSubIntervals()); |
| dsCfg.setWalThreadLocalBufferSize(psCfg.getTlbSize()); |
| dsCfg.setWalArchivePath(psCfg.getWalArchivePath()); |
| dsCfg.setWalAutoArchiveAfterInactivity(psCfg.getWalAutoArchiveAfterInactivity()); |
| dsCfg.setWalFlushFrequency(psCfg.getWalFlushFrequency()); |
| dsCfg.setWalFsyncDelayNanos(psCfg.getWalFsyncDelayNanos()); |
| dsCfg.setWalHistorySize(psCfg.getWalHistorySize()); |
| dsCfg.setWalMode(psCfg.getWalMode()); |
| dsCfg.setWalRecordIteratorBufferSize(psCfg.getWalRecordIteratorBufferSize()); |
| dsCfg.setWalSegments(psCfg.getWalSegments()); |
| dsCfg.setWalSegmentSize(psCfg.getWalSegmentSize()); |
| dsCfg.setWalPath(psCfg.getWalStorePath()); |
| dsCfg.setAlwaysWriteFullPages(psCfg.isAlwaysWriteFullPages()); |
| dsCfg.setMetricsEnabled(psCfg.isMetricsEnabled()); |
| dsCfg.setWriteThrottlingEnabled(psCfg.isWriteThrottlingEnabled()); |
| } |
| |
| cfg.setDataStorageConfiguration(dsCfg); |
| } |
| } |