/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.coordinator.client.service; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.ScheduledExecutorService; import java.util.List; import java.util.ArrayList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.emc.storageos.coordinator.client.service.impl.LeaderSelectorListenerImpl; import com.emc.storageos.services.util.NamedScheduledThreadPoolExecutor; /** * LeaderSelectorListenerForPeriodicTask is an implementation of an adapter to translate the * LeaderSelectorListener interface into arbitrary Runnable interface. * Use this class if you have a Runnable object for a task to be run on a single node periodically. */ public class LeaderSelectorListenerForPeriodicTask extends LeaderSelectorListenerImpl { private static final Log _log = LogFactory.getLog(LeaderSelectorListenerForPeriodicTask.class); List<ScheduledTask> tasks; volatile boolean started; private final ScheduledExecutorService scheduler; public LeaderSelectorListenerForPeriodicTask(Runnable worker, long initialDelay, long interval) { tasks = new ArrayList<>(); tasks.add(new ScheduledTask(worker, initialDelay, interval)); scheduler = new NamedScheduledThreadPoolExecutor(worker.getClass().getSimpleName(), 1); ((NamedScheduledThreadPoolExecutor) scheduler).setAppendTaskName(true); started = false; } public LeaderSelectorListenerForPeriodicTask(ScheduledExecutorService scheduler) { this.scheduler = scheduler; tasks = new ArrayList<>(); started = false; } public boolean addScheduledTask(Runnable worker, long initialDelay, long interval) { if (!started) { synchronized (this) { tasks.add(new ScheduledTask(worker, initialDelay, interval)); return true; } } else { return false; } } protected void startLeadership() throws Exception { started = true; List<ScheduledTask> locTasks; synchronized (this) { locTasks = new ArrayList(tasks); } for (final ScheduledTask task : locTasks) { try { task.taskFuture = scheduler.scheduleAtFixedRate(new Runnable() { public void run() { try { task.taskProcessor.run(); } catch (Exception e) { _log.error("Failed to execute leader's tasks", e); } } }, task.delay, task.interval, TimeUnit.SECONDS); } catch (Exception e) { _log.error("StartLeadership() failed", e); } } } protected void stopLeadership() { List<ScheduledTask> locTasks; synchronized (this) { locTasks = new ArrayList(tasks); } for (final ScheduledTask task : locTasks) { if (task.taskFuture != null) { task.taskFuture.cancel(true); } } started = false; } class ScheduledTask { final Runnable taskProcessor; final private long delay; final private long interval; private ScheduledFuture<?> taskFuture; ScheduledTask(Runnable taskProcessor, long delay, long interval) { this.taskProcessor = taskProcessor; this.delay = delay; this.interval = interval; this.taskFuture = null; } } }