diff options
author | spingel | 2009-10-08 01:04:14 +0000 |
---|---|---|
committer | spingel | 2009-10-08 01:04:14 +0000 |
commit | feb992ab1499da4c25f5a795eae552a532efeceb (patch) | |
tree | 19d0db24a820e3cb1999c006bb094a9b141f4f9e /org.eclipse.mylyn.tasks.core | |
parent | d1ace515cf35e33d036455f0072590a4718e68bb (diff) | |
download | org.eclipse.mylyn.tasks-feb992ab1499da4c25f5a795eae552a532efeceb.tar.gz org.eclipse.mylyn.tasks-feb992ab1499da4c25f5a795eae552a532efeceb.tar.xz org.eclipse.mylyn.tasks-feb992ab1499da4c25f5a795eae552a532efeceb.zip |
NEW - bug 239182: blocked and queued synch jobs
https://bugs.eclipse.org/bugs/show_bug.cgi?id=239182
Diffstat (limited to 'org.eclipse.mylyn.tasks.core')
3 files changed, 121 insertions, 8 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java index 642d7e829..c00993df4 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java @@ -109,6 +109,7 @@ public class TaskDataManager implements ITaskDataManager { Assert.isNotNull(task); final String kind = task.getConnectorKind(); final TaskDataState[] result = new TaskDataState[1]; + final boolean[] changed = new boolean[1]; taskList.run(new ITaskListRunnable() { public void execute(IProgressMonitor monitor) throws CoreException { final File file = getMigratedFile(task, kind); @@ -127,9 +128,11 @@ public class TaskDataManager implements ITaskDataManager { case INCOMING: case INCOMING_NEW: task.setSynchronizationState(SynchronizationState.SYNCHRONIZED); + changed[0] = true; break; case CONFLICT: task.setSynchronizationState(SynchronizationState.OUTGOING); + changed[0] = true; break; } task.setMarkReadPending(true); @@ -137,7 +140,9 @@ public class TaskDataManager implements ITaskDataManager { result[0] = state; } }); - taskList.notifyElementChanged(task); + if (changed[0]) { + taskList.notifyElementChanged(task); + } return result[0]; } @@ -145,6 +150,7 @@ public class TaskDataManager implements ITaskDataManager { final AbstractTask task = (AbstractTask) itask; Assert.isNotNull(task); final String kind = task.getConnectorKind(); + final boolean[] changed = new boolean[1]; taskList.run(new ITaskListRunnable() { public void execute(IProgressMonitor monitor) throws CoreException { final File file = getFile(task, kind); @@ -152,11 +158,15 @@ public class TaskDataManager implements ITaskDataManager { switch (task.getSynchronizationState()) { case SYNCHRONIZED: task.setSynchronizationState(SynchronizationState.OUTGOING); + changed[0] = true; + break; } taskList.addTask(task); } }); - taskList.notifyElementChanged(task); + if (changed[0]) { + taskList.notifyElementChanged(task); + } } public void putUpdatedTaskData(final ITask itask, final TaskData taskData, final boolean user) throws CoreException { @@ -267,6 +277,7 @@ public class TaskDataManager implements ITaskDataManager { final AbstractTask task = (AbstractTask) itask; Assert.isNotNull(task); final String kind = task.getConnectorKind(); + final TaskDataManagerEvent event = new TaskDataManagerEvent(this, itask); taskList.run(new ITaskListRunnable() { public void execute(IProgressMonitor monitor) throws CoreException { File dataFile = getFile(task, kind); @@ -276,15 +287,18 @@ public class TaskDataManager implements ITaskDataManager { switch (task.getSynchronizationState()) { case OUTGOING: task.setSynchronizationState(SynchronizationState.SYNCHRONIZED); + event.setTaskChanged(true); break; case CONFLICT: task.setSynchronizationState(SynchronizationState.INCOMING); + event.setTaskChanged(true); break; } } }); - taskList.notifyElementChanged(task); - final TaskDataManagerEvent event = new TaskDataManagerEvent(this, itask); + if (event.getTaskChanged()) { + taskList.notifyElementChanged(task); + } fireEditsDiscarded(event); } @@ -431,6 +445,7 @@ public class TaskDataManager implements ITaskDataManager { public void setTaskRead(final ITask itask, final boolean read) { final AbstractTask task = (AbstractTask) itask; Assert.isNotNull(task); + final boolean changed[] = new boolean[1]; try { taskList.run(new ITaskListRunnable() { public void execute(IProgressMonitor monitor) throws CoreException { @@ -440,10 +455,12 @@ public class TaskDataManager implements ITaskDataManager { case INCOMING_NEW: task.setSynchronizationState(SynchronizationState.SYNCHRONIZED); task.setMarkReadPending(true); + changed[0] = true; break; case CONFLICT: task.setSynchronizationState(SynchronizationState.OUTGOING); task.setMarkReadPending(true); + changed[0] = true; break; } } else { @@ -451,6 +468,7 @@ public class TaskDataManager implements ITaskDataManager { case SYNCHRONIZED: task.setSynchronizationState(SynchronizationState.INCOMING); task.setMarkReadPending(false); + changed[0] = true; break; } } @@ -460,7 +478,9 @@ public class TaskDataManager implements ITaskDataManager { StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Unexpected error while marking task read", e)); //$NON-NLS-1$ } - taskList.notifyElementChanged(task); + if (changed[0]) { + taskList.notifyElementChanged(task); + } } void putEdits(final ITask itask, final TaskData editsData) throws CoreException { @@ -468,6 +488,7 @@ public class TaskDataManager implements ITaskDataManager { Assert.isNotNull(task); final String kind = task.getConnectorKind(); Assert.isNotNull(editsData); + final boolean[] changed = new boolean[1]; taskList.run(new ITaskListRunnable() { public void execute(IProgressMonitor monitor) throws CoreException { taskDataStore.putEdits(getFile(task, kind), editsData); @@ -476,14 +497,18 @@ public class TaskDataManager implements ITaskDataManager { case INCOMING_NEW: // TODO throw exception instead? task.setSynchronizationState(SynchronizationState.CONFLICT); + changed[0] = true; break; case SYNCHRONIZED: task.setSynchronizationState(SynchronizationState.OUTGOING); + changed[0] = true; break; } } }); - taskList.notifySynchronizationStateChanged(task); + if (changed[0]) { + taskList.notifySynchronizationStateChanged(task); + } } private void fireTaskDataUpdated(final TaskDataManagerEvent event) { diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizationScheduler.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizationScheduler.java new file mode 100644 index 000000000..c2ecf86b1 --- /dev/null +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizationScheduler.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2009 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.core.sync; + +import java.util.HashMap; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; + +/** + * @author Steffen Pingel + */ +public class SynchronizationScheduler { + + public static abstract class Synchronizer<T extends Job> { + + private boolean pendingRequest; + + public abstract T createJob(); + + } + + public HashMap<Object, Synchronizer<?>> synchronizerByObject; + + public SynchronizationScheduler() { + synchronizerByObject = new HashMap<Object, Synchronizer<?>>(); + } + + public void schedule(final Object object, final Synchronizer<?> synchronizer) { + synchronized (synchronizerByObject) { + Synchronizer<?> running = synchronizerByObject.get(object); + if (running != null) { + running.pendingRequest = true; + return; + } else { + synchronizerByObject.put(object, synchronizer); + } + } + + scheduleJob(object, synchronizer); + } + + private void scheduleJob(final Object object, final Synchronizer<?> synchronizer) { + final Job job = synchronizer.createJob(); + final JobChangeAdapter listener = new JobChangeAdapter() { + @Override + public void done(IJobChangeEvent event) { + job.removeJobChangeListener(this); + boolean reschedule; + synchronized (synchronizerByObject) { + reschedule = synchronizer.pendingRequest; + if (synchronizer.pendingRequest) { + synchronizer.pendingRequest = false; + } else { + synchronizerByObject.remove(object); + } + } + if (reschedule) { + scheduleJob(object, synchronizer); + } + } + }; + job.addJobChangeListener(listener); + job.schedule(); + } + + public void cancel(Object object) { + synchronized (synchronizerByObject) { + Synchronizer<?> running = synchronizerByObject.get(object); + if (running != null) { + running.pendingRequest = false; + } + } + } + +} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java index ac8e38de3..c6482d534 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SynchronizeTasksJob.java @@ -254,8 +254,10 @@ public class SynchronizeTasksJob extends SynchronizationJob { } private void resetStatus(ITask task) { - ((AbstractTask) task).setStatus(null); - taskList.notifySynchronizationStateChanged(task); + if (((AbstractTask) task).getStatus() != null) { + ((AbstractTask) task).setStatus(null); + taskList.notifySynchronizationStateChanged(task); + } } private void synchronizeTasks(IProgressMonitor monitor, final TaskRepository repository, Set<ITask> tasks) |