package reactor.spring.core.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.TopicProcessor;
import reactor.core.scheduler.Schedulers;
import reactor.core.scheduler.TimedScheduler;
import reactor.util.concurrent.WaitStrategy;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.util.Assert;
/**
* Implementation of {@link org.springframework.core.task.AsyncTaskExecutor} that uses a {@link TopicProcessor}
* to
* execute tasks.
*
* @author Jon Brisbin
* @author Stephane Maldini
* @since 1.1, 2.5
*/
public class RingBufferAsyncTaskExecutor extends AbstractAsyncTaskExecutor implements BeanNameAware {
private final Logger log = LoggerFactory.getLogger(RingBufferAsyncTaskExecutor.class);
private WaitStrategy waitStrategy;
private TopicProcessor<Runnable> dispatcher;
public RingBufferAsyncTaskExecutor() {
this(Schedulers.timer());
}
public RingBufferAsyncTaskExecutor(TimedScheduler timer) {
super(timer);
}
@Override
public void afterPropertiesSet() throws Exception {
if (!isShared()) {
this.dispatcher = TopicProcessor.create(
getName(),
getBacklog(),
(null != waitStrategy ? waitStrategy : WaitStrategy.blocking())
);
} else {
this.dispatcher = TopicProcessor.share(
getName(),
getBacklog(),
(null != waitStrategy ? waitStrategy : WaitStrategy.blocking())
);
}
if (isAutoStartup()) {
start();
}
}
@Override
public void setBeanName(String name) {
setName(name);
}
@Override
public int getThreads() {
// RingBufferDispatchers are always single-threaded
return 1;
}
@Override
public void setThreads(int threads) {
Assert.isTrue(threads == 1, "A RingBufferAsyncTaskExecutor is always single-threaded");
log.warn("RingBufferAsyncTaskExecutors are always single-threaded. Ignoring request to use " +
threads +
" threads.");
}
/**
* Get the {@link reactor.util.concurrent.WaitStrategy} this {@link reactor.core.queue
* .RingBuffer} is using.
*
* @return the {@link reactor.util.concurrent.WaitStrategy}
*/
public WaitStrategy getWaitStrategy() {
return waitStrategy;
}
/**
* Set the {@link reactor.util.concurrent.WaitStrategy} to use when creating the internal {@link
* reactor.util.concurrent.RingBuffer}.
*
* @param waitStrategy the {@link reactor.util.concurrent.WaitStrategy}
*/
public void setWaitStrategy(WaitStrategy waitStrategy) {
this.waitStrategy = waitStrategy;
}
@Override
protected TopicProcessor<Runnable> getProcessor() {
return dispatcher;
}
}