/*
* Copyright (c) 2016 the original author or authors.
* 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
*/
package org.eclipse.buildship.core.util.progress;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ProgressMonitorWrapper;
/**
* A progress monitor that only publishes the most recent task and sub task at a given rate. Can be used to
* reduce pressure on the UI thread if an operation produces a lot of progress messages in a short
* amount of time, without loosing the benefit of informing the user.
*
* @author Stefan Oehme
*/
public final class RateLimitingProgressMonitor extends ProgressMonitorWrapper {
private final Timer timer;
private final AtomicReference<String> lastTask;
private final AtomicReference<String> lastSubTask;
private final long rate;
private final TimeUnit rateUnit;
public RateLimitingProgressMonitor(IProgressMonitor monitor, long rate, TimeUnit rateUnit) {
super(monitor);
this.timer = new Timer();
this.lastTask = new AtomicReference<String>();
this.lastSubTask = new AtomicReference<String>();
this.rate = rate;
this.rateUnit = rateUnit;
}
@Override
public void beginTask(String name, int totalWork) {
this.timer.scheduleAtFixedRate(forwardMostRecentMessage(), 0, this.rateUnit.toMillis(this.rate));
super.beginTask(name, totalWork);
}
@Override
public void setTaskName(String name) {
this.lastTask.set(name);
}
@Override
public void subTask(String name) {
this.lastSubTask.set(name);
}
@Override
public void done() {
this.timer.cancel();
super.done();
}
private TimerTask forwardMostRecentMessage() {
return new TimerTask() {
@Override
public void run() {
String taskName = RateLimitingProgressMonitor.this.lastTask.getAndSet(null);
if (taskName != null) {
RateLimitingProgressMonitor.super.setTaskName(taskName);
}
String subTaskName = RateLimitingProgressMonitor.this.lastSubTask.getAndSet(null);
if (subTaskName != null) {
RateLimitingProgressMonitor.super.subTask(subTaskName);
}
}
};
}
}