com.espertech.esper.runtime.internal.timer.TimerServiceImpl Maven / Gradle / Ivy
/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.runtime.internal.timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Implementation of the internal clocking service interface.
*/
public final class TimerServiceImpl implements TimerService {
private final String runtimeURI;
private final long msecTimerResolution;
private TimerCallback timerCallback;
private ScheduledThreadPoolExecutor timer;
private EPLTimerTask timerTask;
private final static AtomicInteger NEXT_ID = new AtomicInteger(0);
private final int id;
/**
* Constructor.
*
* @param msecTimerResolution is the millisecond resolution or interval the internal timer thread
* processes schedules
* @param runtimeURI runtime URI
*/
public TimerServiceImpl(String runtimeURI, long msecTimerResolution) {
this.runtimeURI = runtimeURI;
this.msecTimerResolution = msecTimerResolution;
id = NEXT_ID.getAndIncrement();
}
/**
* Returns the timer resolution.
*
* @return the millisecond resolution or interval the internal timer thread
* processes schedules
*/
public long getMsecTimerResolution() {
return msecTimerResolution;
}
public void setCallback(TimerCallback timerCallback) {
this.timerCallback = timerCallback;
}
public final void startInternalClock() {
if (timer != null) {
log.warn(".startInternalClock Internal clock is already started, stop first before starting, operation not completed");
return;
}
if (log.isDebugEnabled()) {
log.debug(".startInternalClock Starting internal clock daemon thread, resolution=" + msecTimerResolution);
}
if (timerCallback == null) {
throw new IllegalStateException("Timer callback not set");
}
getScheduledThreadPoolExecutorDaemonThread();
timerTask = new EPLTimerTask(timerCallback);
// With no delay start every internal
ScheduledFuture> future = timer.scheduleAtFixedRate(timerTask, 0, msecTimerResolution, TimeUnit.MILLISECONDS);
timerTask.setFuture(future);
}
public final void stopInternalClock(boolean warnIfNotStarted) {
if (timer == null) {
if (warnIfNotStarted) {
log.warn(".stopInternalClock Internal clock is already stopped, start first before stopping, operation not completed");
}
return;
}
if (log.isDebugEnabled()) {
log.debug(".stopInternalClock Stopping internal clock daemon thread");
}
try {
timer.shutdown();
timer.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.info("Timer termination wait interval interrupted");
Thread.currentThread().interrupt();
}
timer = null;
}
public void enableStats() {
if (timerTask != null) {
timerTask.enableStats = true;
}
}
public void disableStats() {
if (timerTask != null) {
timerTask.enableStats = false;
// now it is safe to reset stats without any synchronization
timerTask.resetStats();
}
}
public long getMaxDrift() {
return timerTask.maxDrift;
}
public long getLastDrift() {
return timerTask.lastDrift;
}
public long getTotalDrift() {
return timerTask.totalDrift;
}
public long getInvocationCount() {
return timerTask.invocationCount;
}
private void getScheduledThreadPoolExecutorDaemonThread() {
timer = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
// set new thread as daemon thread and name appropriately
public Thread newThread(Runnable r) {
String uri = runtimeURI;
if (runtimeURI == null) {
uri = "default";
}
Thread t = new Thread(r, "com.espertech.esper.Timer-" + uri + "-" + id);
t.setDaemon(true);
return t;
}
});
timer.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
timer.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
}
private static final Logger log = LoggerFactory.getLogger(TimerServiceImpl.class);
}