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.spi; 018 019import java.util.Collection; 020import java.util.concurrent.CountDownLatch; 021 022import org.apache.camel.Exchange; 023import org.apache.camel.StaticService; 024 025/** 026 * A manager to handle async routing engine, when {@link Exchange}s are being handed over from one thread to another, while 027 * the callee thread is blocked waiting for the other threads to complete, before it can continue. 028 * <p/> 029 * This manager offers insight into the state, and allow to force stuck exchanges to be continued and for blocked threads 030 * to be unblocked, which may happen in case of severe malfunctions (such as the system runs out of memory, a 3rd party 031 * never responding, or a timeout not triggering, etc). 032 */ 033public interface AsyncProcessorAwaitManager extends StaticService { 034 035 /** 036 * Utilization statistics of the this manager. 037 */ 038 interface Statistics { 039 040 /** 041 * Total number of threads that has been blocked 042 */ 043 long getThreadsBlocked(); 044 045 /** 046 * Total number of threads that has been forced interrupted 047 */ 048 long getThreadsInterrupted(); 049 050 /** 051 * The total duration time in millis. 052 */ 053 long getTotalDuration(); 054 055 /** 056 * The lowest duration time in millis. 057 */ 058 long getMinDuration(); 059 060 /** 061 * The highest duration time in millis. 062 */ 063 long getMaxDuration(); 064 065 /** 066 * The average duration time in millis. 067 */ 068 long getMeanDuration(); 069 070 /** 071 * Reset the counters 072 */ 073 void reset(); 074 075 /** 076 * Whether statistics is enabled. 077 */ 078 boolean isStatisticsEnabled(); 079 080 /** 081 * Sets whether statistics is enabled. 082 * 083 * @param statisticsEnabled <tt>true</tt> to enable 084 */ 085 void setStatisticsEnabled(boolean statisticsEnabled); 086 } 087 088 /** 089 * Information about the thread and exchange that are inflight. 090 */ 091 interface AwaitThread { 092 093 /** 094 * The thread which is blocked waiting for other threads to signal the callback. 095 */ 096 Thread getBlockedThread(); 097 098 /** 099 * The exchange being processed by the other thread. 100 */ 101 Exchange getExchange(); 102 103 /** 104 * Time in millis the thread has been blocked waiting for the signal. 105 */ 106 long getWaitDuration(); 107 108 /** 109 * The id of the route where the exchange was processed when the thread was set to block. 110 * <p/> 111 * Is <tt>null</tt> if message history is disabled. 112 */ 113 String getRouteId(); 114 115 /** 116 * The id of the node from the route where the exchange was processed when the thread was set to block. 117 * <p/> 118 * Is <tt>null</tt> if message history is disabled. 119 */ 120 String getNodeId(); 121 122 } 123 124 /** 125 * Registers the exchange to await for the callback to be triggered by another thread which has taken over processing 126 * this exchange. The current thread will await until that callback happens in the future (blocking until this happens). 127 * 128 * @param exchange the exchange 129 * @param latch the latch used to wait for other thread to signal when its done 130 */ 131 void await(Exchange exchange, CountDownLatch latch); 132 133 /** 134 * Triggered when the other thread is done processing the exchange, to signal to the waiting thread is done, and can take 135 * over control to further process the exchange. 136 * 137 * @param exchange the exchange 138 * @param latch the latch used to wait for other thread to signal when its done 139 */ 140 void countDown(Exchange exchange, CountDownLatch latch); 141 142 /** 143 * Number of threads that are blocked waiting for other threads to trigger the callback when they are done processing 144 * the exchange. 145 */ 146 int size(); 147 148 /** 149 * A <i>read-only</i> browser of the {@link AwaitThread}s that are currently inflight. 150 */ 151 Collection<AwaitThread> browse(); 152 153 /** 154 * To interrupt an exchange which may seem as stuck, to force the exchange to continue, 155 * allowing any blocking thread to be released. 156 * <p/> 157 * <b>Important:</b> Use this with caution as the other thread is still assumed to be process the exchange. Though 158 * if it appears as the exchange is <i>stuck</i>, then this method can remedy this, by forcing the latch to count-down 159 * so the blocked thread can continue. An exception is set on the exchange which allows Camel's error handler to deal 160 * with this malfunctioned exchange. 161 * 162 * @param exchangeId the exchange id to interrupt. 163 */ 164 void interrupt(String exchangeId); 165 166 /** 167 * To interrupt an exchange which may seem as stuck, to force the exchange to continue, 168 * allowing any blocking thread to be released. 169 * <p/> 170 * <b>Important:</b> Use this with caution as the other thread is still assumed to be process the exchange. Though 171 * if it appears as the exchange is <i>stuck</i>, then this method can remedy this, by forcing the latch to count-down 172 * so the blocked thread can continue. An exception is set on the exchange which allows Camel's error handler to deal 173 * with this malfunctioned exchange. 174 * 175 * @param exchange the exchange to interrupt. 176 */ 177 void interrupt(Exchange exchange); 178 179 /** 180 * Whether to interrupt any blocking threads during stopping. 181 * <p/> 182 * This is enabled by default which allows Camel to release any blocked thread during shutting down Camel itself. 183 */ 184 boolean isInterruptThreadsWhileStopping(); 185 186 /** 187 * Sets whether to interrupt any blocking threads during stopping. 188 * <p/> 189 * This is enabled by default which allows Camel to release any blocked thread during shutting down Camel itself. 190 */ 191 void setInterruptThreadsWhileStopping(boolean interruptThreadsWhileStopping); 192 193 /** 194 * Gets the utilization statistics of this manager 195 * 196 * @return the utilization statistics 197 */ 198 Statistics getStatistics(); 199 200}