001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.impl; 018 019import java.util.Locale; 020import java.util.concurrent.ScheduledExecutorService; 021import java.util.concurrent.ScheduledFuture; 022import java.util.concurrent.TimeUnit; 023 024import org.apache.camel.CamelContext; 025import org.apache.camel.Consumer; 026import org.apache.camel.spi.ScheduledPollConsumerScheduler; 027import org.apache.camel.util.ObjectHelper; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * Default {@link org.apache.camel.impl.ScheduledBatchPollingConsumer}. 033 */ 034public class DefaultScheduledPollConsumerScheduler extends org.apache.camel.support.ServiceSupport implements ScheduledPollConsumerScheduler { 035 036 private static final Logger LOG = LoggerFactory.getLogger(DefaultScheduledPollConsumerScheduler.class); 037 private CamelContext camelContext; 038 private Consumer consumer; 039 private ScheduledExecutorService scheduledExecutorService; 040 private boolean shutdownExecutor; 041 private volatile ScheduledFuture<?> future; 042 private Runnable task; 043 044 private long initialDelay = 1000; 045 private long delay = 500; 046 private TimeUnit timeUnit = TimeUnit.MILLISECONDS; 047 private boolean useFixedDelay = true; 048 049 public CamelContext getCamelContext() { 050 return camelContext; 051 } 052 053 public void setCamelContext(CamelContext camelContext) { 054 this.camelContext = camelContext; 055 } 056 057 public long getInitialDelay() { 058 return initialDelay; 059 } 060 061 public void setInitialDelay(long initialDelay) { 062 this.initialDelay = initialDelay; 063 } 064 065 public long getDelay() { 066 return delay; 067 } 068 069 public void setDelay(long delay) { 070 this.delay = delay; 071 } 072 073 public TimeUnit getTimeUnit() { 074 return timeUnit; 075 } 076 077 public void setTimeUnit(TimeUnit timeUnit) { 078 this.timeUnit = timeUnit; 079 } 080 081 public boolean isUseFixedDelay() { 082 return useFixedDelay; 083 } 084 085 public void setUseFixedDelay(boolean useFixedDelay) { 086 this.useFixedDelay = useFixedDelay; 087 } 088 089 public ScheduledExecutorService getScheduledExecutorService() { 090 return scheduledExecutorService; 091 } 092 093 public void setScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) { 094 this.scheduledExecutorService = scheduledExecutorService; 095 } 096 097 @Override 098 public void onInit(Consumer consumer) { 099 this.consumer = consumer; 100 } 101 102 @Override 103 public void scheduleTask(Runnable task) { 104 this.task = task; 105 } 106 107 @Override 108 public void unscheduleTask() { 109 if (future != null) { 110 future.cancel(false); 111 } 112 } 113 114 @Override 115 public void startScheduler() { 116 // only schedule task if we have not already done that 117 if (future == null) { 118 if (isUseFixedDelay()) { 119 if (LOG.isDebugEnabled()) { 120 LOG.debug("Scheduling poll (fixed delay) with initialDelay: {}, delay: {} ({}) for: {}", 121 new Object[]{getInitialDelay(), getDelay(), getTimeUnit().name().toLowerCase(Locale.ENGLISH), consumer.getEndpoint()}); 122 } 123 future = scheduledExecutorService.scheduleWithFixedDelay(task, getInitialDelay(), getDelay(), getTimeUnit()); 124 } else { 125 if (LOG.isDebugEnabled()) { 126 LOG.debug("Scheduling poll (fixed rate) with initialDelay: {}, delay: {} ({}) for: {}", 127 new Object[]{getInitialDelay(), getDelay(), getTimeUnit().name().toLowerCase(Locale.ENGLISH), consumer.getEndpoint()}); 128 } 129 future = scheduledExecutorService.scheduleAtFixedRate(task, getInitialDelay(), getDelay(), getTimeUnit()); 130 } 131 } 132 } 133 134 @Override 135 public boolean isSchedulerStarted() { 136 return future != null; 137 } 138 139 @Override 140 protected void doStart() throws Exception { 141 ObjectHelper.notNull(consumer, "Consumer", this); 142 ObjectHelper.notNull(camelContext, "CamelContext", this); 143 ObjectHelper.notNull(task, "Task", this); 144 145 // if no existing executor provided, then create a new thread pool ourselves 146 if (scheduledExecutorService == null) { 147 // we only need one thread in the pool to schedule this task 148 this.scheduledExecutorService = getCamelContext().getExecutorServiceManager() 149 .newSingleThreadScheduledExecutor(consumer, consumer.getEndpoint().getEndpointUri()); 150 // and we should shutdown the thread pool when no longer needed 151 this.shutdownExecutor = true; 152 } 153 } 154 155 @Override 156 protected void doStop() throws Exception { 157 if (future != null) { 158 LOG.debug("This consumer is stopping, so cancelling scheduled task: " + future); 159 future.cancel(true); 160 future = null; 161 } 162 163 if (shutdownExecutor && scheduledExecutorService != null) { 164 getCamelContext().getExecutorServiceManager().shutdownNow(scheduledExecutorService); 165 scheduledExecutorService = null; 166 future = null; 167 } 168 } 169 170}