Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Michel-Lemieux2003-11-14 20:53:15 +0000
committerJean Michel-Lemieux2003-11-14 20:53:15 +0000
commit36d91249ffa9118e046bcd97881a280161e06b8e (patch)
tree5f49480c21544f9d8d690495d56617eec2e92ec6
parentdfc1b9cf2f6bb8aae44badb1155a2effcb2acfdd (diff)
downloadeclipse.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
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/BackgroundEventHandler.java97
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java27
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java25
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

Back to the top