Java tutorial
/******************************************************************************* * Copyright 2013 Michael Marconi * * Licensed 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 oncue.scheduler; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import oncue.backingstore.BackingStore; import oncue.common.comparators.JobComparator; import oncue.common.messages.Job; import akka.event.LoggingAdapter; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Sets; /** * An encapsulated job queue of unscheduled {@linkplain Job}s that relies on a backing store for * persistence. */ public class UnscheduledJobs { // The persistent backing store private final BackingStore backingStore; private final LoggingAdapter log; // The prioritised queue of unscheduled jobs private SortedSet<Job> unscheduledJobs = new TreeSet<>(new JobComparator()); /** * @param backingStore is an instance of {@linkplain BackingStore} */ public UnscheduledJobs(BackingStore backingStore, LoggingAdapter log, Comparator<Job> jobComparator) { this.unscheduledJobs = new TreeSet<>(jobComparator); this.backingStore = backingStore; this.log = log; restoreJobs(); } /** * Add a job to the queue */ public void addJob(Job job) { backingStore.addUnscheduledJob(job); unscheduledJobs.add(job); } /** * @return the number of jobs in the queue */ public int getSize() { return unscheduledJobs.size(); } /** * @return the set of worker types that enqueued jobs require to process */ public Set<String> getWorkerTypes() { Set<String> workerTypes = new HashSet<>(); Iterator<Job> itrJobs = unscheduledJobs.iterator(); while (itrJobs.hasNext()) { Job job = itrJobs.next(); workerTypes.add(job.getWorkerType()); } return workerTypes; } /** * @return true if there are no more unscheduled jobs */ public boolean isEmpty() { return unscheduledJobs.isEmpty(); } /** * Determine if there are unscheduled jobs for the specified worker type. */ public boolean isWorkAvailable(Set<String> workerTypes) { Iterator<Job> itrJobs = unscheduledJobs.iterator(); while (itrJobs.hasNext()) { Job job = itrJobs.next(); if (workerTypes.contains(job.getWorkerType())) return true; } return false; } /** * @return a thread-safe iterator over the unscheduled jobs. */ public Iterator<Job> iterator() { return unscheduledJobs.iterator(); } /** * Remove a job from anywhere in the queue * * @return a boolean, indicating if the removal was successful */ public boolean removeJobById(final long jobId) { boolean removed = Iterables.removeIf(unscheduledJobs, new Predicate<Job>() { @Override public boolean apply(Job input) { return input.getId() == jobId; } }); if (removed) backingStore.removeUnscheduledJobById(jobId); return removed; } /** * Remove a list of jobs from anywhere in the queue * * @return a boolean, indicating if the removal was successful */ public boolean removeJobs(List<Job> jobs) { final Set<Long> jobIds = Sets.newHashSet(Iterators.transform(jobs.iterator(), new Function<Job, Long>() { @Override public Long apply(Job input) { return input.getId(); } })); boolean removed = Iterables.removeIf(unscheduledJobs, new Predicate<Job>() { @Override public boolean apply(Job input) { return jobIds.contains(input.getId()); } }); if (backingStore != null && removed) for (Job job : jobs) { backingStore.removeUnscheduledJobById(job.getId()); } return removed; } /** * Restore any scheduled and unscheduled jobs from the backing store */ private void restoreJobs() { List<Job> restoredJobs = backingStore.restoreJobs(); if (restoredJobs != null && !restoredJobs.isEmpty()) log.info("Restoring {} jobs from the backing store", restoredJobs.size()); unscheduledJobs.addAll(restoredJobs); } }