/* * Copyright 2014-2015 JKOOL, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jkoolcloud.tnt4j; import java.io.IOException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import com.jkoolcloud.tnt4j.config.DefaultConfigFactory; import com.jkoolcloud.tnt4j.config.TrackerConfig; import com.jkoolcloud.tnt4j.core.ActivityListener; import com.jkoolcloud.tnt4j.core.OpLevel; import com.jkoolcloud.tnt4j.tracker.TrackingActivity; /** * <p> * This class allows scheduled execution of tracking activities * based on user defined interval. * </p> * * * @version $Revision: 1 $ * * @see TrackingActivity * @see ActivityListener */ public class ActivityScheduler { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2, new TaskThreadFactory("ActivityScheduler/task")); private String name; private TrackingLogger logger; private ScheduledFuture<?> future; private Runnable activityTask; private OpLevel opLevel = OpLevel.INFO; /** * Creates a scheduler with specified name * * @param name scheduler name */ public ActivityScheduler(String name) { this(name, null); } /** * Creates a scheduler with specified name * * @param name scheduler name * @param listener activity listener invoked when scheduled activity starts and stops * * @see ActivityListener */ public ActivityScheduler(String name, ActivityListener listener) { this.name = name; TrackerConfig config = DefaultConfigFactory.getInstance().getConfig(name); if (listener != null) config.setActivityListener(listener); this.logger = TrackingLogger.getInstance(config.build()); this.logger.setKeepThreadContext(false); } /** * Assign a default severity level to all scheduled activity events * * @param severity associated with all timing activities, events */ public void setOpLevel(OpLevel severity) { opLevel = severity; } /** * Default severity level for all scheduled activity events * * @return severity associated with all timing activities, events */ public OpLevel getOpLevel() { return opLevel; } /** * Name associated with this object * * @return object name */ public String getName() { return name; } /** * Assign an activity listener to be used when scheduled activity starts/stops * * @param listener activity listener invoked when scheduled activity starts and stops * @return instance of the same scheduler * @see ActivityListener */ public ActivityScheduler setListener(ActivityListener listener) { logger.getConfiguration().setActivityListener(listener); return this; } /** * Get an activity listener used when scheduled activity starts/stops * * @return return currently associated activity listener * @see ActivityListener */ public ActivityListener getListener() { return logger.getConfiguration().getActivityListener(); } /** * Schedule activity with a specified period in milliseconds * * @param period in milliseconds */ public void schedule(long period) { schedule("ActivityTask", period, period, TimeUnit.MILLISECONDS); } /** * Schedule activity with a specified period in milliseconds * * @param name activity name * @param period in milliseconds */ public void schedule(String name, long period) { schedule(name, period, period, TimeUnit.MILLISECONDS); } /** * Schedule activity with a given name and timing details * * @param name activity name * @param period in specified time units * @param tunit time unit for period */ public void schedule(String name, long period, TimeUnit tunit) { schedule(name, period, period, TimeUnit.MILLISECONDS); } /** * Schedule activity with a given name and timing details * * @param name activity name * @param initialDelay in specified time units * @param period in specified time units * @param tunit time unit for period */ public void schedule(String name, long initialDelay, long period, TimeUnit tunit) { schedule(name, period, period, tunit, opLevel); } /** * Schedule activity with a given name and timing details * * @param name activity name * @param initialDelay in specified time units * @param period in specified time units * @param tunit time unit for period * @param severity associated with all timing activities, events */ public void schedule(String name, long initialDelay, long period, TimeUnit tunit, OpLevel severity) { if (future == null || future.isCancelled()) { activityTask = newActivityTask(logger, name, severity); future = scheduler.scheduleAtFixedRate(activityTask, initialDelay, period, tunit); } else { throw new IllegalStateException("Already scheduled"); } } /** * Cancel currently scheduled activity * */ public void cancel() { cancel(false); } /** * Cancel currently scheduled activity * * @param interrupt may interrupt currently running activity */ public void cancel (boolean interrupt) { future.cancel(interrupt); } /** * Open current scheduled activity instance. * @throws IOException if error opening instance * */ public void open() throws IOException { logger.open(); } /** * Close current scheduled activity instance. * */ public void close() { try { cancel(true); if (future != null) { future.get(); } } catch (Throwable ex) {} finally { logger.close(); } } /** * Obtain {@link TrackingLogger} instance for logging * * @return tracking logger instance */ public TrackingLogger getLogger() { return this.logger; } /** * Override this calls to return custom instances of * {@code Runnable} which will be invoked per specified schedule. * @param lg tracking logger instance * @param name of the new activity task * @param level associated with the task * @return {@code Runnable} instance */ protected Runnable newActivityTask(TrackingLogger lg, String name, OpLevel level) { return new ActivityTask(logger, name, (level == null? opLevel: level)); } } class TaskThreadFactory implements ThreadFactory { int count = 0; String prefix; TaskThreadFactory(String pfix) { prefix = pfix; } @Override public Thread newThread(Runnable r) { Thread task = new Thread(r, prefix + "-" + count++); task.setDaemon(true); return task; } }