Bugfix: Changing Task state breaks comparator in ShowQueue
This can happens if you have a long queue and the state of a task (DONE, CANCELLED, RUNNING, READY, SLEEPING, OTHER) changes while the sorting is ongoing. The reason this generates an error is because the Task State defines the tasks’ place in the queue. If Task state changes while the sorting of the queue is ongoing the Comparator violates its contract of: X<Y, Y<Z => X<Z and throws: IllegalArgumentException: Comparison mehtod violates its general contract! Fixed this bug by saving a snapshot of the state and delay of the tasks in a wrapper. * Introduced interface TaskInfo that is implemented by QueueTaskInfo * Added getTaskInfos method in WorkQueue decoupling it from ShowQueue implementation by Interface and factory. Signed-off-by: Gustaf Lundh <gustaf.lundh@sonymobile.com> Change-Id: Iea17046aea1b8c6119cfc663438e17f663e05b22
This commit is contained in:
committed by
Shawn Pearce
parent
ef30ea4a4b
commit
ae4349db63
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// 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 com.google.gerrit.server.git;
|
||||
|
||||
public interface TaskInfoFactory<T> {
|
||||
T getTaskInfo(WorkQueue.Task<?> task);
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.extensions.events.LifecycleListener;
|
||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
import com.google.gerrit.reviewdb.client.Project.NameKey;
|
||||
@@ -26,6 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -115,6 +117,16 @@ public class WorkQueue {
|
||||
return r;
|
||||
}
|
||||
|
||||
public <T> List<T> getTaskInfos(TaskInfoFactory<T> factory) {
|
||||
List<T> taskInfos = Lists.newArrayList();
|
||||
for (Executor exe : queues) {
|
||||
for (Task<?> task : exe.getTasks()) {
|
||||
taskInfos.add(factory.getTaskInfo(task));
|
||||
}
|
||||
}
|
||||
return taskInfos;
|
||||
}
|
||||
|
||||
/** Locate a task by its unique id, null if no task matches. */
|
||||
public Task<?> getTask(final int id) {
|
||||
Task<?> result = null;
|
||||
@@ -186,7 +198,7 @@ public class WorkQueue {
|
||||
Task<V> task;
|
||||
|
||||
if (runnable instanceof ProjectRunnable) {
|
||||
task = new ProjectTask<V>((ProjectRunnable)runnable, r, this, id);
|
||||
task = new ProjectTask<V>((ProjectRunnable) runnable, r, this, id);
|
||||
} else {
|
||||
task = new Task<V>(runnable, r, this, id);
|
||||
}
|
||||
@@ -214,6 +226,10 @@ public class WorkQueue {
|
||||
void addAllTo(final List<Task<?>> list) {
|
||||
list.addAll(all.values()); // iterator is thread safe
|
||||
}
|
||||
|
||||
Collection<Task<?>> getTasks() {
|
||||
return all.values();
|
||||
}
|
||||
}
|
||||
|
||||
/** Runnable needing to know it was canceled. */
|
||||
@@ -351,8 +367,9 @@ public class WorkQueue {
|
||||
}
|
||||
}
|
||||
|
||||
/** Same as Task class, but with a reference to ProjectRunnable, used to retrieve
|
||||
* the project name from the operation queued
|
||||
/**
|
||||
* Same as Task class, but with a reference to ProjectRunnable, used to
|
||||
* retrieve the project name from the operation queued
|
||||
**/
|
||||
public static class ProjectTask<V> extends Task<V> implements ProjectRunnable {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user