/*
* Copyright 2015 Philip Cronje
*
* 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 net.za.slyfox.dyn53.extip;
import net.za.slyfox.dyn53.bean.Lifecycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Implements a {@link Lifecycle} object that manages a scheduled task to discover the external IP of the network the
* application is running in.
*/
final class ExternalIpDiscoveryLifecycle implements Lifecycle {
private final Provider<Runnable> commandProvider;
private final long delay;
private final ScheduledExecutorService executorService;
private final long initialDelay;
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* Initializes the {@code ExternalIpDiscoveryLifecycle} with configuration variables and dependencies.
*
* @param initialDelay the delay before the initial scheduled task should begin executing
* @param delay the delay between scheduled tasks, measured from the end of the previous task
* @param commandProvider a {@code Provider} that will supply the tasks to execute
* @param executorService the scheduled executor service that will schedule and execute tasks
* @throws NullPointerException if a required dependency is {@code null}
*/
@Inject
ExternalIpDiscoveryLifecycle(@Named("initialDelay") long initialDelay, @Named("delay") long delay,
Provider<Runnable> commandProvider, ScheduledExecutorService executorService) {
this.commandProvider = Objects.requireNonNull(commandProvider);
this.delay = delay;
this.executorService = Objects.requireNonNull(executorService);
this.initialDelay = initialDelay;
}
/**
* Schedules the external IP discovery task.
*/
@Override
public void start() {
logger.info("Scheduling external IP discovery to execute every {} seconds, after initial delay of {} seconds",
delay, initialDelay);
executorService.scheduleWithFixedDelay(commandProvider.get(), initialDelay, delay, TimeUnit.SECONDS);
}
/**
* Gracefully shuts down the scheduled executor service. If, after one minute, the executor service has not shut
* down, this method will return, but may result in dangling threads/tasks.
*/
@Override
public void stop() {
logger.info("Shutting down external IP discovery scheduler");
executorService.shutdownNow();
logger.info("Waiting for termination of scheduled task");
try {
if(!executorService.awaitTermination(1, TimeUnit.MINUTES)) {
logger.warn("Scheduled task is still running, stopping anyway");
} else {
logger.info("Shutdown of external IP discovery schedule complete");
}
} catch(InterruptedException e) {
logger.debug("Interrupted while waiting for termination of scheduled task");
}
}
}