diff options
author | Jean Michel-Lemieux | 2003-11-14 20:53:15 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2003-11-14 20:53:15 +0000 |
commit | 36d91249ffa9118e046bcd97881a280161e06b8e (patch) | |
tree | 5f49480c21544f9d8d690495d56617eec2e92ec6 | |
parent | dfc1b9cf2f6bb8aae44badb1155a2effcb2acfdd (diff) | |
download | eclipse.platform.team-36d91249ffa9118e046bcd97881a280161e06b8e.tar.gz eclipse.platform.team-36d91249ffa9118e046bcd97881a280161e06b8e.tar.xz eclipse.platform.team-36d91249ffa9118e046bcd97881a280161e06b8e.zip |
Bug 46552 Sync view flickers a lot on full build
3 files changed, 95 insertions, 54 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/BackgroundEventHandler.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/BackgroundEventHandler.java index d6b645b1d..46dc3da27 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/BackgroundEventHandler.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/BackgroundEventHandler.java @@ -14,18 +14,20 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.team.internal.core.ExceptionCollector; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.core.*; /** - * Thsi class provides the infrastucture for processing events in the background + * This class provides the infrastucture for processing/dispatching of events in the + * background. This is useful to allow blocking operations to be more responsive by + * delegating event processing and UI updating to background job. + * <p> + * This is also useful for scheduling changes that require a workspace lock but can't + * be performed in a change delta. + * </p> + * @since 3.0 */ public abstract class BackgroundEventHandler { @@ -41,6 +43,15 @@ public abstract class BackgroundEventHandler { // Accumulate exceptions that occur private ExceptionCollector errors; + // time the last dispath took + private long processingEventsDuration = 0L; + + // time between event dispatches + private long DISPATCH_DELAY = 1500; + + // time to wait for messages to be queued + private long WAIT_DELAY = 1000; + /** * Resource event class. The type is specific to subclasses. */ @@ -89,7 +100,6 @@ public abstract class BackgroundEventHandler { } } - protected BackgroundEventHandler() { errors = new ExceptionCollector( @@ -112,10 +122,10 @@ public abstract class BackgroundEventHandler { return processEvents(monitor); } public boolean shouldRun() { - return hasUnprocessedEvents(); + return ! isQueueEmpty(); } public boolean shouldSchedule() { - return hasUnprocessedEvents(); + return ! isQueueEmpty(); } }; eventHandlerJob.addJobChangeListener(new JobChangeAdapter() { @@ -137,7 +147,7 @@ public abstract class BackgroundEventHandler { synchronized(this) { awaitingProcessing.clear(); } - } else if (hasUnprocessedEvents()) { + } else if (! isQueueEmpty()) { // An event squeaked in as the job was finishing. Reschedule the job. schedule(); } @@ -158,7 +168,7 @@ public abstract class BackgroundEventHandler { /** * Return the text to be displayed as the title for any errors that occur. - * @return + * @return the title to display in an error message */ protected abstract String getErrorsTitle(); @@ -179,17 +189,20 @@ public abstract class BackgroundEventHandler { } /** - * Queue the event and start the job if it's not already doing work. + * Queue the event and start the job if it's not already doing work. If the job is + * already running then notify in case it was waiting. */ protected synchronized void queueEvent(Event event) { if (Policy.DEBUG_BACKGROUND_EVENTS) { System.out.println("Event queued on " + getName() + ":" + event.toString()); //$NON-NLS-1$ //$NON-NLS-2$ } awaitingProcessing.add(event); - if (!isShutdown() - && eventHandlerJob != null - && eventHandlerJob.getState() == Job.NONE) { - schedule(); + if (!isShutdown() && eventHandlerJob != null) { + if(eventHandlerJob.getState() == Job.NONE) { + schedule(); + } else { + notify(); + } } } @@ -198,7 +211,7 @@ public abstract class BackgroundEventHandler { * @return Event to be processed */ private synchronized Event nextElement() { - if (isShutdown() || !hasUnprocessedEvents()) { + if (isShutdown() || isQueueEmpty()) { return null; } return (Event) awaitingProcessing.remove(0); @@ -208,8 +221,8 @@ public abstract class BackgroundEventHandler { * Return whether there are unprocessed events on the event queue. * @return whether there are unprocessed events on the queue */ - protected synchronized boolean hasUnprocessedEvents() { - return !awaitingProcessing.isEmpty(); + protected synchronized boolean isQueueEmpty() { + return awaitingProcessing.isEmpty(); } /** @@ -229,12 +242,17 @@ public abstract class BackgroundEventHandler { subMonitor.beginTask(null, 1024); Event event; + processingEventsDuration = System.currentTimeMillis(); while ((event = nextElement()) != null && ! isShutdown()) { try { processEvent(event, subMonitor); if (Policy.DEBUG_BACKGROUND_EVENTS) { System.out.println("Event processed on " + getName() + ":" + event.toString()); //$NON-NLS-1$ //$NON-NLS-2$ } + if(isReadyForDispath()) { + dispatchEvents(); + processingEventsDuration = System.currentTimeMillis(); + } } catch (CoreException e) { // handle exception but keep going handleException(e); @@ -247,6 +265,39 @@ public abstract class BackgroundEventHandler { } /** + * Notify clients of processed events. + */ + protected abstract void dispatchEvents() throws TeamException; + + /** + * Returns <code>true</code> if processed events should be dispatched and + * <code>false</code> otherwise. Events are dispatched at regular intervals + * to avoid fine grain events causing the UI to be too jumpy. Also, if the + * events queue is empty we will wait a small amount of time to allow + * pending events to be queued. The queueEvent notifies when events are + * queued. + * @return <code>true</code> if processed events should be dispatched and + * <code>false</code> otherwise + */ + private boolean isReadyForDispath() { + long duration = System.currentTimeMillis() - processingEventsDuration; + if(duration >= DISPATCH_DELAY) { + return true; + } + synchronized(this) { + if(! isQueueEmpty()) { + return false; + } + try { + wait(WAIT_DELAY); + } catch (InterruptedException e) { + // just continue + } + } + return isQueueEmpty(); + } + + /** * Handle the exception by recording it in the errors list. * @param e */ diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java index 96b24060c..4f921b0c2 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java @@ -10,18 +10,14 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core.syncinfo; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; +import java.util.*; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.subscribers.BackgroundEventHandler; -import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; import org.eclipse.team.internal.ccvs.core.Policy; +import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; /** * This class handles resources changes that are reported in deltas @@ -33,8 +29,6 @@ public class DeferredResourceChangeHandler extends BackgroundEventHandler { private Set changedIgnoreFiles = new HashSet(); - private int NOTIFICATION_BATCHING_NUMBER = 10; - /* (non-Javadoc) * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#getName() */ @@ -57,13 +51,7 @@ public class DeferredResourceChangeHandler extends BackgroundEventHandler { switch (type) { case IGNORE_FILE_CHANGED : changedIgnoreFiles.add(event.getResource()); - } - - if (!hasUnprocessedEvents() - || changedIgnoreFiles.size() > NOTIFICATION_BATCHING_NUMBER) { - EclipseSynchronizer.getInstance().ignoreFilesChanged(getParents(changedIgnoreFiles)); - changedIgnoreFiles.clear(); - } + } } private IContainer[] getParents(Set files) { @@ -79,4 +67,11 @@ public class DeferredResourceChangeHandler extends BackgroundEventHandler { queueEvent(new Event(file, IGNORE_FILE_CHANGED, IResource.DEPTH_ZERO)); } + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#dispatchEvents() + */ + protected void dispatchEvents() throws TeamException { + EclipseSynchronizer.getInstance().ignoreFilesChanged(getParents(changedIgnoreFiles)); + changedIgnoreFiles.clear(); + } } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java index ca164eb46..f57aaff96 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java @@ -10,9 +10,7 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.sets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; @@ -34,9 +32,6 @@ import org.eclipse.team.ui.synchronize.actions.SubscriberAction; * one. */ public class SubscriberEventHandler extends BackgroundEventHandler { - // The number of events to process before feeding into the set. - private static final int NOTIFICATION_BATCHING_NUMBER = 10; - // The set that receives notification when the resource synchronization state // has been calculated by the job. private SyncSetInputFromSubscriber set; @@ -300,13 +295,13 @@ public class SubscriberEventHandler extends BackgroundEventHandler { resultCache.addAll(Arrays.asList(events)); break; } - - if (!hasUnprocessedEvents() - || resultCache.size() > NOTIFICATION_BATCHING_NUMBER) { - dispatchEvents( - (SubscriberEvent[]) resultCache.toArray( - new SubscriberEvent[resultCache.size()])); - resultCache.clear(); - } } -} + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#dispatchEvents() + */ + protected void dispatchEvents() { + dispatchEvents((SubscriberEvent[]) resultCache.toArray(new SubscriberEvent[resultCache.size()])); + resultCache.clear(); + } +}
\ No newline at end of file |