Search in sources :

Example 1 with CollisionJobContext

use of org.apache.ignite.spi.collision.CollisionJobContext in project ignite by apache.

the class FifoQueueCollisionSpi method onCollision.

/** {@inheritDoc} */
@Override
public void onCollision(CollisionContext ctx) {
    assert ctx != null;
    Collection<CollisionJobContext> activeJobs = ctx.activeJobs();
    Collection<CollisionJobContext> waitJobs = ctx.waitingJobs();
    // Save initial sizes to limit iteration.
    int activeSize = activeJobs.size();
    int waitSize = waitJobs.size();
    waitingCnt = waitSize;
    runningCnt = activeSize;
    heldCnt = ctx.heldJobs().size();
    int parallelJobsNum0 = parallelJobsNum;
    Iterator<CollisionJobContext> it = null;
    if (activeSize < parallelJobsNum0) {
        it = waitJobs.iterator();
        while (it.hasNext()) {
            CollisionJobContext waitCtx = it.next();
            waitCtx.activate();
            if (--waitSize == 0)
                // No more waiting jobs to process (to limit iterations).
                return;
            // Take actual size, since it might have been changed.
            if (activeJobs.size() >= parallelJobsNum0)
                // Max active jobs threshold reached.
                break;
        }
    }
    int waitJobsNum0 = waitJobsNum;
    // Take actual size, since it might have been changed.
    if (waitJobs.size() > waitJobsNum0) {
        if (it == null)
            it = waitJobs.iterator();
        while (it.hasNext()) {
            CollisionJobContext waitCtx = it.next();
            waitCtx.cancel();
            if (--waitSize == 0)
                // No more waiting jobs to process (to limit iterations).
                return;
            // Take actual size, since it might have been changed.
            if (waitJobs.size() <= waitJobsNum0)
                // No need to reject more jobs.
                return;
        }
    }
}
Also used : CollisionJobContext(org.apache.ignite.spi.collision.CollisionJobContext)

Example 2 with CollisionJobContext

use of org.apache.ignite.spi.collision.CollisionJobContext in project ignite by apache.

the class JobStealingCollisionSpi method sortJobs.

/**
     * Sort jobs by priority from high to lowest value.
     *
     * @param waitJobs Waiting jobs.
     * @param waitSize Snapshot size.
     * @return Sorted waiting jobs by priority.
     */
private Collection<CollisionJobContext> sortJobs(Collection<CollisionJobContext> waitJobs, int waitSize) {
    List<CollisionJobContext> passiveList = new ArrayList<>(waitJobs.size());
    int i = 0;
    for (CollisionJobContext waitJob : waitJobs) {
        passiveList.add(waitJob);
        if (i++ == waitSize)
            break;
    }
    Collections.sort(passiveList, comparator());
    return passiveList;
}
Also used : ArrayList(java.util.ArrayList) CollisionJobContext(org.apache.ignite.spi.collision.CollisionJobContext)

Example 3 with CollisionJobContext

use of org.apache.ignite.spi.collision.CollisionJobContext in project ignite by apache.

the class JobStealingCollisionSpi method checkBusy.

/**
     * Check if node is busy and activate/reject proper number of jobs.
     *
     * @param waitJobs Waiting jobs.
     * @param activeJobs Active jobs.
     * @return Number of rejected jobs.
     */
private int checkBusy(Collection<CollisionJobContext> waitJobs, Collection<CollisionJobContext> activeJobs) {
    int activeSize = activeJobs.size();
    int waitSize = waitJobs.size();
    waitingNum = waitJobs.size();
    runningNum = activeSize;
    IgniteSpiContext ctx = getSpiContext();
    int activated = 0;
    int rejected = 0;
    Collection<CollisionJobContext> waitPriJobs = sortJobs(waitJobs, waitSize);
    int activeJobsThreshold0 = activeJobsThreshold;
    int waitJobsThreshold0 = waitJobsThreshold;
    for (CollisionJobContext waitCtx : waitPriJobs) {
        if (activeJobs.size() < activeJobsThreshold0) {
            activated++;
            // We also need to make sure that job is not being rejected by another thread.
            synchronized (waitCtx.getJobContext()) {
                waitCtx.activate();
            }
        } else if (stealReqs.get() > 0) {
            if (waitCtx.getJob().getClass().isAnnotationPresent(JobStealingDisabled.class))
                continue;
            // Collision count attribute.
            Integer stealingCnt = waitCtx.getJobContext().getAttribute(STEALING_ATTEMPT_COUNT_ATTR);
            // has not been exceeded.
            if (stealingCnt != null) {
                // If job exceeded failover threshold, skip it.
                if (stealingCnt >= maxStealingAttempts) {
                    if (log.isDebugEnabled())
                        log.debug("Waiting job exceeded stealing attempts and won't be rejected " + "(will try other jobs on waiting list): " + waitCtx);
                    continue;
                }
            } else
                stealingCnt = 0;
            // Check if allowed to reject job.
            int jobsToReject = waitPriJobs.size() - activated - rejected - waitJobsThreshold0;
            if (log.isDebugEnabled())
                log.debug("Jobs to reject count [jobsToReject=" + jobsToReject + ", waitCtx=" + waitCtx + ']');
            if (jobsToReject <= 0)
                break;
            Integer pri = waitCtx.getJobContext().getAttribute(STEALING_PRIORITY_ATTR);
            if (pri == null)
                pri = DFLT_JOB_PRIORITY;
            // counter to prevent excessive iteration over nodes under load.
            for (Iterator<Entry<UUID, MessageInfo>> iter = rcvMsgMap.entrySet().iterator(); iter.hasNext() && stealReqs.get() > 0; ) {
                Entry<UUID, MessageInfo> entry = iter.next();
                UUID nodeId = entry.getKey();
                // Node has left topology.
                if (ctx.node(nodeId) == null) {
                    iter.remove();
                    continue;
                }
                MessageInfo info = entry.getValue();
                synchronized (info) {
                    int jobsAsked = info.jobsToSteal();
                    assert jobsAsked >= 0;
                    // Skip nodes that have not asked for jobs to steal.
                    if (jobsAsked == 0)
                        // Move to next node.
                        continue;
                    // If message is expired, ignore it.
                    if (info.expired()) {
                        // Subtract expired messages.
                        stealReqs.addAndGet(-info.jobsToSteal());
                        info.reset(0);
                        continue;
                    }
                    // Check that waiting job has thief node in topology.
                    boolean found = false;
                    for (UUID id : waitCtx.getTaskSession().getTopology()) {
                        if (id.equals(nodeId)) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        if (log.isDebugEnabled())
                            log.debug("Thief node does not belong to task topology [thief=" + nodeId + ", task=" + waitCtx.getTaskSession() + ']');
                        continue;
                    }
                    if (stealReqs.get() <= 0)
                        break;
                    // rejected by another thread.
                    synchronized (waitCtx.getJobContext()) {
                        boolean cancel = waitCtx.getJobContext().getAttribute(THIEF_NODE_ATTR) == null;
                        if (cancel) {
                            // Mark job as stolen.
                            waitCtx.getJobContext().setAttribute(THIEF_NODE_ATTR, nodeId);
                            waitCtx.getJobContext().setAttribute(STEALING_ATTEMPT_COUNT_ATTR, stealingCnt + 1);
                            waitCtx.getJobContext().setAttribute(STEALING_PRIORITY_ATTR, pri + 1);
                            if (log.isDebugEnabled())
                                log.debug("Will try to reject job due to steal request [ctx=" + waitCtx + ", thief=" + nodeId + ']');
                            int i = stealReqs.decrementAndGet();
                            if (i >= 0 && waitCtx.cancel()) {
                                rejected++;
                                info.reset(jobsAsked - 1);
                                if (log.isDebugEnabled())
                                    log.debug("Rejected job due to steal request [ctx=" + waitCtx + ", nodeId=" + nodeId + ']');
                            } else {
                                if (log.isDebugEnabled())
                                    log.debug("Failed to reject job [i=" + i + ']');
                                waitCtx.getJobContext().setAttribute(THIEF_NODE_ATTR, null);
                                waitCtx.getJobContext().setAttribute(STEALING_ATTEMPT_COUNT_ATTR, stealingCnt);
                                waitCtx.getJobContext().setAttribute(STEALING_PRIORITY_ATTR, pri);
                                stealReqs.incrementAndGet();
                            }
                        }
                    }
                    // Move to next job.
                    break;
                }
            }
        } else
            // No more jobs to steal or activate.
            break;
    }
    return rejected;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteSpiContext(org.apache.ignite.spi.IgniteSpiContext) Entry(java.util.Map.Entry) Iterator(java.util.Iterator) CollisionJobContext(org.apache.ignite.spi.collision.CollisionJobContext) UUID(java.util.UUID)

Example 4 with CollisionJobContext

use of org.apache.ignite.spi.collision.CollisionJobContext in project ignite by apache.

the class GridJobStealingCollisionSpiCustomTopologySelfTest method testThiefNodeNotInTopology.

/**
     * @throws Exception If test failed.
     */
public void testThiefNodeNotInTopology() throws Exception {
    List<CollisionJobContext> waitCtxs = new ArrayList<>(2);
    final ClusterNode node = getSpiContext().nodes().iterator().next();
    Collections.addAll(waitCtxs, new GridTestCollisionJobContext(createTaskSession(node), IgniteUuid.randomUuid()), new GridTestCollisionJobContext(createTaskSession(node), IgniteUuid.randomUuid()), new GridTestCollisionJobContext(createTaskSession(node), IgniteUuid.randomUuid()));
    Collection<CollisionJobContext> activeCtxs = new ArrayList<>(1);
    // Add active.
    Collections.addAll(activeCtxs, new GridTestCollisionJobContext(createTaskSession(node), IgniteUuid.randomUuid()));
    // Emulate message to steal 2 jobs.
    getSpiContext().triggerMessage(rmtNode2, new JobStealingRequest(2));
    getSpi().onCollision(new GridCollisionTestContext(activeCtxs, waitCtxs));
    // Check no action.
    checkNoAction((GridTestCollisionJobContext) waitCtxs.get(0));
    checkNoAction((GridTestCollisionJobContext) waitCtxs.get(1));
    checkNoAction((GridTestCollisionJobContext) waitCtxs.get(2));
    // Make sure that no message was sent.
    Serializable msg1 = getSpiContext().removeSentMessage(getSpiContext().localNode());
    assert msg1 == null;
    Serializable mgs2 = getSpiContext().removeSentMessage(rmtNode1);
    assert mgs2 == null;
    Serializable msg3 = getSpiContext().removeSentMessage(rmtNode2);
    assert msg3 == null;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) Serializable(java.io.Serializable) ArrayList(java.util.ArrayList) GridTestCollisionJobContext(org.apache.ignite.spi.collision.GridTestCollisionJobContext) CollisionJobContext(org.apache.ignite.spi.collision.CollisionJobContext) GridCollisionTestContext(org.apache.ignite.spi.collision.GridCollisionTestContext) GridTestCollisionJobContext(org.apache.ignite.spi.collision.GridTestCollisionJobContext)

Example 5 with CollisionJobContext

use of org.apache.ignite.spi.collision.CollisionJobContext in project ignite by apache.

the class GridJobStealingCollisionSpiSelfTest method testOnePassiveOneActiveJobs.

/**
     * @throws Exception If test failed.
     */
public void testOnePassiveOneActiveJobs() throws Exception {
    List<CollisionJobContext> waitCtxs = new ArrayList<>(1);
    // Add passive.
    Collections.addAll(waitCtxs, new GridTestCollisionJobContext(createTaskSession(), IgniteUuid.randomUuid()));
    List<CollisionJobContext> activeCtxs = new ArrayList<>(1);
    // Add active.
    Collections.addAll(activeCtxs, new GridTestCollisionJobContext(createTaskSession(), IgniteUuid.randomUuid()));
    ClusterNode rmtNode = F.first(getSpiContext().remoteNodes());
    getSpiContext().triggerMessage(rmtNode, new JobStealingRequest(1));
    getSpi().onCollision(new GridCollisionTestContext(activeCtxs, waitCtxs));
    // Active job.
    checkNoAction((GridTestCollisionJobContext) activeCtxs.get(0));
    // Rejected.
    checkRejected((GridTestCollisionJobContext) waitCtxs.get(0), rmtNode);
    // Make sure that no message was sent.
    Serializable msg = getSpiContext().removeSentMessage(rmtNode);
    assert msg == null;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) Serializable(java.io.Serializable) ArrayList(java.util.ArrayList) CollisionJobContext(org.apache.ignite.spi.collision.CollisionJobContext) GridTestCollisionJobContext(org.apache.ignite.spi.collision.GridTestCollisionJobContext) GridCollisionTestContext(org.apache.ignite.spi.collision.GridCollisionTestContext) GridTestCollisionJobContext(org.apache.ignite.spi.collision.GridTestCollisionJobContext)

Aggregations

CollisionJobContext (org.apache.ignite.spi.collision.CollisionJobContext)35 GridCollisionTestContext (org.apache.ignite.spi.collision.GridCollisionTestContext)32 GridTestCollisionJobContext (org.apache.ignite.spi.collision.GridTestCollisionJobContext)25 Serializable (java.io.Serializable)16 ClusterNode (org.apache.ignite.cluster.ClusterNode)13 ArrayList (java.util.ArrayList)10 GridTestCollisionTaskSession (org.apache.ignite.spi.collision.GridTestCollisionTaskSession)5 GridTestNode (org.apache.ignite.testframework.GridTestNode)3 GridTestJobContext (org.apache.ignite.GridTestJobContext)2 CI1 (org.apache.ignite.internal.util.typedef.CI1)2 Iterator (java.util.Iterator)1 Entry (java.util.Map.Entry)1 UUID (java.util.UUID)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 IgniteSpiContext (org.apache.ignite.spi.IgniteSpiContext)1