Force AbstractMessageBarrierEndpoint and subclasses to use the TaskScheduler supplied via TaskSchedulerAware for scheduling the ReaperThread. Introducing a Schedulers helper class for creating a default TaskScheduler.
This commit is contained in:
@@ -22,19 +22,19 @@ import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.integration.channel.BlockingChannel;
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
|
||||
import org.springframework.integration.endpoint.MessageEndpoint;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.scheduling.IntervalTrigger;
|
||||
import org.springframework.integration.scheduling.TaskSchedulerAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -43,7 +43,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* Base class for {@link MessageBarrier}-based MessageHandlers.
|
||||
* A {@link MessageEndpoint} implementation that waits for a group of
|
||||
* {@link Message Messages} to arrive and processes them together.
|
||||
* Uses a {@link MessageBarrier} to store messages and to decide how
|
||||
* Uses a {@link MessageBarr ier} to store messages and to decide how
|
||||
* the messages should be released.
|
||||
* <p>
|
||||
* Each {@link Message} that is received by this endpoint will be associated with
|
||||
@@ -60,7 +60,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHandlingEndpoint {
|
||||
public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHandlingEndpoint implements TaskSchedulerAware {
|
||||
|
||||
public final static long DEFAULT_SEND_TIMEOUT = 1000;
|
||||
|
||||
@@ -89,15 +89,9 @@ public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHand
|
||||
|
||||
protected volatile BlockingQueue<Object> trackedCorrelationIds;
|
||||
|
||||
protected final ScheduledExecutorService executor;
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
|
||||
public AbstractMessageBarrierEndpoint(ScheduledExecutorService executor) {
|
||||
this.executor = (executor != null) ? executor : Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
|
||||
private ScheduledFuture<?> reaperFutureTask;
|
||||
|
||||
/**
|
||||
* Specify a channel for sending Messages that arrive after their aggregation
|
||||
@@ -154,10 +148,20 @@ public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHand
|
||||
protected void initialize() throws Exception {
|
||||
super.initialize();
|
||||
this.trackedCorrelationIds = new ArrayBlockingQueue<Object>(this.trackedCorrelationIdCapacity);
|
||||
this.executor.scheduleWithFixedDelay(new ReaperTask(),
|
||||
this.reaperInterval, this.reaperInterval, TimeUnit.MILLISECONDS);
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
this.reaperFutureTask = this.getTaskScheduler().schedule(new ReaperTask(), new IntervalTrigger(reaperInterval, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
this.reaperFutureTask.cancel(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Message<?> handle(Message<?> message) {
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package org.springframework.integration.aggregator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -51,8 +51,8 @@ public class AggregatorEndpoint extends AbstractMessageBarrierEndpoint {
|
||||
* scheduling a background maintenance thread. If <code>null</code>, a new
|
||||
* single-threaded executor will be created.
|
||||
*/
|
||||
public AggregatorEndpoint(Aggregator aggregator, ScheduledExecutorService executor) {
|
||||
super(executor);
|
||||
public AggregatorEndpoint(Aggregator aggregator, TaskScheduler executor) {
|
||||
super();
|
||||
Assert.notNull(aggregator, "'aggregator' must not be null");
|
||||
this.aggregator = aggregator;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.integration.aggregator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageHeaders;
|
||||
@@ -41,15 +40,6 @@ public class ResequencerEndpoint extends AbstractMessageBarrierEndpoint {
|
||||
private volatile boolean releasePartialSequences = true;
|
||||
|
||||
|
||||
public ResequencerEndpoint() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ResequencerEndpoint(ScheduledExecutorService executor) {
|
||||
super(executor);
|
||||
}
|
||||
|
||||
|
||||
public void setReleasePartialSequences(boolean releasePartialSequences) {
|
||||
this.releasePartialSequences = releasePartialSequences;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,9 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor;
|
||||
@@ -46,11 +44,11 @@ import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.channel.MessagePublishingErrorHandler;
|
||||
import org.springframework.integration.endpoint.MessageEndpoint;
|
||||
import org.springframework.integration.endpoint.MessagingGateway;
|
||||
import org.springframework.integration.scheduling.Schedulers;
|
||||
import org.springframework.integration.scheduling.SimpleTaskScheduler;
|
||||
import org.springframework.integration.scheduling.TaskScheduler;
|
||||
import org.springframework.integration.scheduling.TaskSchedulerAware;
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -165,12 +163,8 @@ public class DefaultMessageBus implements MessageBus, ApplicationContextAware, A
|
||||
}
|
||||
Assert.notNull(this.applicationContext, "ApplicationContext must not be null");
|
||||
if (this.taskScheduler == null) {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(DEFAULT_DISPATCHER_POOL_SIZE);
|
||||
executor.setThreadFactory(new CustomizableThreadFactory("message-bus-"));
|
||||
executor.setRejectedExecutionHandler(new CallerRunsPolicy());
|
||||
executor.afterPropertiesSet();
|
||||
this.taskScheduler = new SimpleTaskScheduler(executor);
|
||||
this.taskScheduler = Schedulers.createDefaultTaskExecutor(DEFAULT_DISPATCHER_POOL_SIZE,
|
||||
new CustomizableThreadFactory("message-bus-"));
|
||||
}
|
||||
if (this.getErrorChannel() == null) {
|
||||
this.registerChannel(new DefaultErrorChannel());
|
||||
|
||||
@@ -126,6 +126,7 @@ public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint
|
||||
"failed to start endpoint, no taskScheduler available");
|
||||
this.pollerFuture = this.getTaskScheduler().schedule(this.poller, this.poller.getTrigger());
|
||||
}
|
||||
onStart();
|
||||
this.running = true;
|
||||
}
|
||||
}
|
||||
@@ -141,9 +142,27 @@ public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint
|
||||
else if (this.pollerFuture != null) {
|
||||
this.pollerFuture.cancel(true);
|
||||
}
|
||||
onStop();
|
||||
this.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses might override this to supply their own start code (e.g. if they start threads
|
||||
* on their own). This method will be called within the lifecycleMonitor.
|
||||
*/
|
||||
protected void onStart() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses might override this to supply their own stop code (e.g. if they stop threads
|
||||
* on their own).This method will be called within the lifecycleMonitor.
|
||||
*
|
||||
*/
|
||||
protected void onStop() {
|
||||
|
||||
}
|
||||
|
||||
public final void onMessage(Message<?> message) {
|
||||
if (message == null || message.getPayload() == null) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.integration.scheduling;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
|
||||
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* Helper class for creating predefined {@link TaskScheduler} classes.
|
||||
*
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class Schedulers {
|
||||
|
||||
public static TaskScheduler createDefaultTaskExecutor(int poolSize, ThreadFactory threadFactory) {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(poolSize);
|
||||
executor.setThreadFactory(threadFactory);
|
||||
executor.setRejectedExecutionHandler(new CallerRunsPolicy());
|
||||
executor.afterPropertiesSet();
|
||||
return new SimpleTaskScheduler(executor);
|
||||
}
|
||||
|
||||
public static TaskScheduler createDefaultTaskScheduler(int poolSize) {
|
||||
return createDefaultTaskExecutor(poolSize, null);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user