Search in sources :

Example 1 with JobHandler

use of org.apache.sling.event.impl.jobs.JobHandler in project sling by apache.

the class QueueJobCache method loadJobs.

/**
     * Load the next N x numberOf(topics) jobs.
     * @param topic The topic
     * @param topicResource The parent resource of the jobs
     * @return The cache which will be filled with the jobs.
     */
private List<JobImpl> loadJobs(final String queueName, final String topic, final Resource topicResource, final StatisticsManager statisticsManager) {
    logger.debug("Loading jobs from topic {}", topic);
    final List<JobImpl> list = new ArrayList<JobImpl>();
    final AtomicBoolean scanTopic = new AtomicBoolean(false);
    JobTopicTraverser.traverse(logger, topicResource, new JobTopicTraverser.JobCallback() {

        @Override
        public boolean handle(final JobImpl job) {
            if (job.getProcessingStarted() == null && !job.hasReadErrors()) {
                list.add(job);
                statisticsManager.jobQueued(queueName, topic);
                if (list.size() == maxPreloadLimit) {
                    scanTopic.set(true);
                }
            } else if (job.getProcessingStarted() != null) {
                logger.debug("Ignoring job {} - processing already started.", job);
            } else {
                // error reading job
                scanTopic.set(true);
                if (job.isReadErrorRecoverable()) {
                    logger.debug("Ignoring job {} due to recoverable read errors.", job);
                } else {
                    logger.debug("Failing job {} due to unrecoverable read errors.", job);
                    final JobHandler handler = new JobHandler(job, null, configuration);
                    handler.finished(JobState.ERROR, true, null);
                }
            }
            return list.size() < maxPreloadLimit;
        }
    });
    if (scanTopic.get()) {
        synchronized (this.topicsWithNewJobs) {
            this.topicsWithNewJobs.add(topic);
        }
    }
    logger.debug("Caching {} jobs for topic {}", list.size(), topic);
    return list;
}
Also used : JobHandler(org.apache.sling.event.impl.jobs.JobHandler) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) JobImpl(org.apache.sling.event.impl.jobs.JobImpl) ArrayList(java.util.ArrayList) JobTopicTraverser(org.apache.sling.event.impl.jobs.JobTopicTraverser)

Example 2 with JobHandler

use of org.apache.sling.event.impl.jobs.JobHandler in project sling by apache.

the class QueueJobCache method getNextJob.

/**
     * Get the next job.
     * This method is potentially called concurrently, and
     * {@link #reschedule(String, JobHandler, StatisticsManager)} and {@link #handleNewTopics(Set)}
     * can be called concurrently.
     * @param jobConsumerManager The job consumer manager
     * @param statisticsManager The statistics manager
     * @param queue The queue
     * @param doFull Whether to do a full scan
     * @return The job handler or {@code null}.
     */
public JobHandler getNextJob(final JobConsumerManager jobConsumerManager, final StatisticsManager statisticsManager, final Queue queue, final boolean doFull) {
    JobHandler handler = null;
    if (!this.queueIsBlocked.get()) {
        synchronized (this.cache) {
            boolean retry;
            do {
                retry = false;
                if (this.cache.isEmpty()) {
                    final Set<String> checkingTopics = new HashSet<String>();
                    synchronized (this.topicsWithNewJobs) {
                        checkingTopics.addAll(this.topicsWithNewJobs);
                        this.topicsWithNewJobs.clear();
                    }
                    if (doFull) {
                        checkingTopics.addAll(this.topics);
                    }
                    if (!checkingTopics.isEmpty()) {
                        this.loadJobs(queue.getName(), checkingTopics, statisticsManager);
                    }
                }
                if (!this.cache.isEmpty()) {
                    final JobImpl job = this.cache.remove(0);
                    final JobExecutor consumer = jobConsumerManager.getExecutor(job.getTopic());
                    handler = new JobHandler(job, consumer, this.configuration);
                    if (consumer != null) {
                        if (!handler.startProcessing(queue)) {
                            statisticsManager.jobDequeued(queue.getName(), handler.getJob().getTopic());
                            if (logger.isDebugEnabled()) {
                                logger.debug("Discarding removed job {}", Utility.toString(job));
                            }
                            handler = null;
                            retry = true;
                        }
                    } else {
                        statisticsManager.jobDequeued(queue.getName(), handler.getJob().getTopic());
                        // no consumer on this instance, assign to another instance
                        handler.reassign();
                        handler = null;
                        retry = true;
                    }
                }
            } while (handler == null && retry);
        }
    }
    return handler;
}
Also used : JobHandler(org.apache.sling.event.impl.jobs.JobHandler) JobImpl(org.apache.sling.event.impl.jobs.JobImpl) JobExecutor(org.apache.sling.event.jobs.consumer.JobExecutor) HashSet(java.util.HashSet)

Example 3 with JobHandler

use of org.apache.sling.event.impl.jobs.JobHandler in project sling by apache.

the class JobQueueImpl method startJobs.

/**
     * Start the job queue.
     * This method might be called concurrently, therefore we use a guard
     */
public void startJobs() {
    if (this.startJobsGuard.compareAndSet(false, true)) {
        // we start as many jobs in parallel as possible
        while (this.running && !this.isOutdated.get() && !this.isSuspended() && this.available.tryAcquire()) {
            boolean started = false;
            this.lock.writeLock().lock();
            try {
                final JobHandler handler = this.cache.getNextJob(this.services.jobConsumerManager, this.services.statisticsManager, this, this.doFullCacheSearch.getAndSet(false));
                if (handler != null) {
                    started = true;
                    this.threadPool.execute(new Runnable() {

                        @Override
                        public void run() {
                            // update thread priority and name
                            final Thread currentThread = Thread.currentThread();
                            final String oldName = currentThread.getName();
                            final int oldPriority = currentThread.getPriority();
                            currentThread.setName(oldName + "-" + handler.getJob().getQueueName() + "(" + handler.getJob().getTopic() + ")");
                            if (configuration.getThreadPriority() != null) {
                                switch(configuration.getThreadPriority()) {
                                    case NORM:
                                        currentThread.setPriority(Thread.NORM_PRIORITY);
                                        break;
                                    case MIN:
                                        currentThread.setPriority(Thread.MIN_PRIORITY);
                                        break;
                                    case MAX:
                                        currentThread.setPriority(Thread.MAX_PRIORITY);
                                        break;
                                }
                            }
                            try {
                                startJob(handler);
                            } finally {
                                currentThread.setPriority(oldPriority);
                                currentThread.setName(oldName);
                            }
                            // and try to launch another job
                            startJobs();
                        }
                    });
                } else {
                    // no job available, stop look
                    break;
                }
            } finally {
                if (!started) {
                    this.available.release();
                }
                this.lock.writeLock().unlock();
            }
        }
        this.startJobsGuard.set(false);
    }
}
Also used : JobHandler(org.apache.sling.event.impl.jobs.JobHandler)

Example 4 with JobHandler

use of org.apache.sling.event.impl.jobs.JobHandler in project sling by apache.

the class JobQueueImpl method finishedJob.

/**
     * Handle job finish and determine whether to reschedule or cancel the job
     */
private boolean finishedJob(final String jobId, final Job.JobState resultState, final boolean isAsync) {
    this.services.configuration.getAuditLogger().debug("FINISHED {} : {}", resultState, jobId);
    this.logger.debug("Received finish for job {}, resultState={}", jobId, resultState);
    // get job handler
    final JobHandler handler;
    // let's remove the event from our processing list
    synchronized (this.processingJobsLists) {
        handler = this.processingJobsLists.remove(jobId);
    }
    if (!this.running) {
        this.logger.warn("Queue is not running anymore. Discarding finish for {}", jobId);
        return false;
    }
    if (handler == null) {
        this.logger.warn("This job has never been started by this queue: {}", jobId);
        return false;
    }
    // handle the rescheduling of the job
    final RescheduleInfo rescheduleInfo = this.handleReschedule(handler, resultState);
    if (!rescheduleInfo.reschedule) {
        // we keep cancelled jobs and succeeded jobs if the queue is configured like this.
        final boolean keepJobs = rescheduleInfo.state != Job.JobState.SUCCEEDED || this.configuration.isKeepJobs();
        handler.finished(rescheduleInfo.state, keepJobs, rescheduleInfo.processingTime);
    } else {
        this.reschedule(handler);
    }
    // update statistics
    this.services.statisticsManager.jobEnded(this.queueName, handler.getJob().getTopic(), rescheduleInfo.finalState, rescheduleInfo.processingTime);
    // send notification
    NotificationUtility.sendNotification(this.services.eventAdmin, rescheduleInfo.finalState.getTopic(), handler.getJob(), rescheduleInfo.processingTime);
    return rescheduleInfo.reschedule;
}
Also used : JobHandler(org.apache.sling.event.impl.jobs.JobHandler)

Example 5 with JobHandler

use of org.apache.sling.event.impl.jobs.JobHandler in project sling by apache.

the class QueueManager method restart.

/**
     * Outdate all queues.
     */
private void restart() {
    // let's rename/close all queues and clear them
    synchronized (queuesLock) {
        final List<JobQueueImpl> queues = new ArrayList<>(this.queues.values());
        for (final JobQueueImpl queue : queues) {
            this.outdateQueue(queue);
        }
    }
    // check if we're still active
    final JobManagerConfiguration config = this.configuration;
    if (config != null) {
        final List<Job> rescheduleList = this.configuration.clearJobRetryList();
        for (final Job j : rescheduleList) {
            final JobHandler jh = new JobHandler((JobImpl) j, null, this.configuration);
            jh.reschedule();
        }
    }
}
Also used : JobHandler(org.apache.sling.event.impl.jobs.JobHandler) JobManagerConfiguration(org.apache.sling.event.impl.jobs.config.JobManagerConfiguration) ArrayList(java.util.ArrayList) Job(org.apache.sling.event.jobs.Job)

Aggregations

JobHandler (org.apache.sling.event.impl.jobs.JobHandler)5 ArrayList (java.util.ArrayList)2 JobImpl (org.apache.sling.event.impl.jobs.JobImpl)2 HashSet (java.util.HashSet)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 JobTopicTraverser (org.apache.sling.event.impl.jobs.JobTopicTraverser)1 JobManagerConfiguration (org.apache.sling.event.impl.jobs.config.JobManagerConfiguration)1 Job (org.apache.sling.event.jobs.Job)1 JobExecutor (org.apache.sling.event.jobs.consumer.JobExecutor)1