All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.yudichev.jiotty.common.async.SingleThreadedSchedulingExecutor Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
package net.yudichev.jiotty.common.async;

import com.google.common.collect.Sets;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.assistedinject.Assisted;
import net.yudichev.jiotty.common.lang.BaseIdempotentCloseable;
import net.yudichev.jiotty.common.lang.Closeable;
import net.yudichev.jiotty.common.lang.Runnables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.time.Duration;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;

import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

final class SingleThreadedSchedulingExecutor implements SchedulingExecutor {
    private static final Logger logger = LoggerFactory.getLogger(SingleThreadedSchedulingExecutor.class);

    private final Set scheduleHandles = Sets.newConcurrentHashSet();
    private final ScheduledExecutorService executor;

    @Inject
    SingleThreadedSchedulingExecutor(@Assisted String threadNameBase) {
        executor = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
                .setNameFormat(threadNameBase + "-%s")
                .setDaemon(true)
                .build());
    }

    @Override
    public void execute(Runnable command) {
        executor.execute(Runnables.guarded(logger, "task", command));
    }

    @Override
    public Closeable schedule(Duration delay, Runnable command) {
        Closeable scheduledHandle = new ScheduledHandle(executor.schedule(
                Runnables.guarded(logger, "scheduled task", command), delay.toNanos(), NANOSECONDS));
        scheduleHandles.add(scheduledHandle);
        return scheduledHandle;
    }

    @Override
    public Closeable scheduleAtFixedRate(Duration initialDelay, Duration period, Runnable command) {
        Closeable scheduledHandle = new ScheduledHandle(
                executor.scheduleAtFixedRate(Runnables.guarded(logger, "scheduled task", command), initialDelay.toNanos(), period.toNanos(), NANOSECONDS));
        scheduleHandles.add(scheduledHandle);
        return scheduledHandle;
    }

    @Override
    public void close() {
        Closeable.forCloseables(scheduleHandles).close();
        if (!MoreExecutors.shutdownAndAwaitTermination(executor, 10, SECONDS)) {
            logger.warn("Was not able to gracefully stop executor in 10 seconds");
        }
    }

    private final class ScheduledHandle extends BaseIdempotentCloseable {
        private final Closeable executorHandle;

        private ScheduledHandle(Future scheduledFuture) {
            executorHandle = () -> scheduledFuture.cancel(false);
        }

        @Override
        protected void doClose() {
            executorHandle.close();
            scheduleHandles.remove(this);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy