/* * 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.managers.collision; import java.util.Collection; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.SkipDaemon; import org.apache.ignite.internal.managers.GridManagerAdapter; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.collision.CollisionContext; import org.apache.ignite.spi.collision.CollisionExternalListener; import org.apache.ignite.spi.collision.CollisionJobContext; import org.apache.ignite.spi.collision.CollisionSpi; import org.jetbrains.annotations.Nullable; /** * This class defines a collision manager. */ @SkipDaemon public class GridCollisionManager extends GridManagerAdapter<CollisionSpi> { /** Reference for external listener. */ private final AtomicReference<CollisionExternalListener> extLsnr = new AtomicReference<>(); /** * @param ctx Grid kernal context. */ public GridCollisionManager(GridKernalContext ctx) { super(ctx, ctx.config().getCollisionSpi()); } /** {@inheritDoc} */ @Override public void start(boolean activeOnStart) throws IgniteCheckedException { startSpi(); if (enabled()) { getSpi().setExternalCollisionListener(new CollisionExternalListener() { @Override public void onExternalCollision() { CollisionExternalListener lsnr = extLsnr.get(); if (lsnr != null) lsnr.onExternalCollision(); } }); } else U.warn(log, "Collision resolution is disabled (all jobs will be activated upon arrival)."); if (log.isDebugEnabled()) log.debug(startInfo()); } /** {@inheritDoc} */ @Override public void stop(boolean cancel) throws IgniteCheckedException { if (ctx.config().isDaemon()) return; stopSpi(); // Unsubscribe. if (enabled()) getSpi().setExternalCollisionListener(null); if (log.isDebugEnabled()) log.debug(stopInfo()); } /** * Unsets external collision listener. */ public void unsetCollisionExternalListener() { if (enabled()) getSpi().setExternalCollisionListener(null); } /** * @param lsnr Listener to external collision events. */ public void setCollisionExternalListener(@Nullable CollisionExternalListener lsnr) { if (enabled()) { if (lsnr != null && !extLsnr.compareAndSet(null, lsnr)) assert false : "Collision external listener has already been set " + "(perhaps need to add support for multiple listeners)"; else if (log.isDebugEnabled()) log.debug("Successfully set external collision listener: " + lsnr); } } /** * @param waitJobs List of waiting jobs. * @param activeJobs List of active jobs. * @param heldJobs List of held jobs. */ public void onCollision( final Collection<CollisionJobContext> waitJobs, final Collection<CollisionJobContext> activeJobs, final Collection<CollisionJobContext> heldJobs) { if (enabled()) { if (log.isDebugEnabled()) log.debug("Resolving job collisions [waitJobs=" + waitJobs + ", activeJobs=" + activeJobs + ']'); getSpi().onCollision(new CollisionContext() { @Override public Collection<CollisionJobContext> activeJobs() { return activeJobs; } @Override public Collection<CollisionJobContext> waitingJobs() { return waitJobs; } @Override public Collection<CollisionJobContext> heldJobs() { return heldJobs; } }); } } }