/* Copyright (c) 2011 Danish Maritime Authority
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
package dk.dma.ais.abnormal.stat;
import com.google.inject.Inject;
import dk.dma.ais.reader.AisDirectoryReader;
import dk.dma.ais.reader.AisReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.NumberFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ProgressIndicator {
private static final Logger LOG = LoggerFactory.getLogger(ProgressIndicator.class);
private final AisReader reader;
private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
private long startTime;
private static final int PROGRESS_INDICATION_PERIOD_MINUTES = 10;
@Inject
public ProgressIndicator(AisReader reader) {
this.reader = reader;
LOG.info("ProgressIndicator created (" + this + ").");
}
public void init() {
LOG.debug("reader: " + reader);
if (reader instanceof AisDirectoryReader) {
LOG.info("Scanning input files...");
((AisDirectoryReader) reader).getEstimatedFractionOfPacketsRead();
LOG.debug("Scanning input files... done.");
}
}
public void start() {
LOG.debug("Starting progress indicator.");
startTime = System.currentTimeMillis();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
showProgress();
}
private void showProgress() {
if (reader instanceof AisDirectoryReader) {
final float fractionCompleted = ((AisDirectoryReader) reader).getEstimatedFractionOfPacketsRead();
final NumberFormat pctFormatter = NumberFormat.getPercentInstance();
final String pctComplete = pctFormatter.format(fractionCompleted);
final long elapsedMillis = System.currentTimeMillis() - startTime;
final float pace = fractionCompleted / elapsedMillis; // Pace since start (should use pace over last hour?)
final float fractionRemaining = 1 - fractionCompleted;
final long remainingMillis = (long) (fractionRemaining / pace);
LOG.debug("elapsedMillis: " + elapsedMillis + ", pace: " + pace + ", fractionRemaining: " + fractionRemaining + ", remainingMillis: " + remainingMillis);
final long estimatedTimeOfCompletion = startTime + elapsedMillis + remainingMillis;
LOG.info("Training is " + pctComplete + " complete. Estimated time of completion is " + new Date(estimatedTimeOfCompletion) + ".");
}
}
}, 1 /* early output */, PROGRESS_INDICATION_PERIOD_MINUTES, TimeUnit.MINUTES);
}
public void shutdown() {
LOG.debug("Stopping progress indicator.");
scheduledExecutorService.shutdownNow();
try {
scheduledExecutorService.awaitTermination(PROGRESS_INDICATION_PERIOD_MINUTES * 2, TimeUnit.MINUTES);
} catch (InterruptedException e) {
LOG.error(e.getMessage(), e);
}
}
}