@@ -161,18 +161,30 @@ void runContainer() {
161161 final Queue <Message > extraMessages = new LinkedList <>();
162162
163163 final BlockingRunnable shutdownMessageRetriever = startupMessageRetriever (messageRetriever , extraMessages ::addAll );
164-
164+ log . info ( "Container '{}' is beginning to process messages" , identifier );
165165 processMessagesFromRetriever (messageBroker , messageRetriever , messageProcessor , messageResolver ,
166166 messageBrokerExecutorService , messageProcessingExecutorService );
167167 log .info ("Container '{}' is being shutdown" , identifier );
168+ log .debug ("Container '{}' is shutting down MessageRetriever" , identifier );
168169 shutdownMessageRetriever .run ();
169- processExtraMessages (messageBroker , messageProcessor , messageResolver , messageBrokerExecutorService ,
170- messageProcessingExecutorService , extraMessages );
170+ log .debug ("Container '{}' has stopped the MessageRetriever" , identifier );
171+ if (!extraMessages .isEmpty () && shouldProcessAnyExtraRetrievedMessagesOnShutdown ()) {
172+ log .info ("Container '{}' is processing {} extra messages before shutdown" , identifier , extraMessages .size ());
173+ processExtraMessages (messageBroker , messageProcessor , messageResolver , messageBrokerExecutorService ,
174+ messageProcessingExecutorService , extraMessages );
175+ }
176+ log .debug ("Container '{}' is shutting down MessageProcessor threads" , identifier );
171177 shutdownMessageProcessingThreads (messageProcessingExecutorService );
178+ log .debug ("Container '{}' has shutdown the MessageProcessor threads" , identifier );
179+ log .debug ("Container '{}' is shutting down MessageResolver" , identifier );
172180 shutdownMessageResolver .run ();
181+ log .debug ("Container '{}' has shutdown the MessageResolver" , identifier );
182+ log .debug ("Container '{}' is shutting down MessageBroker" , identifier );
183+ shutdownMessageBroker (messageBrokerExecutorService );
184+ log .debug ("Container '{}' has shutdown the MessageBroker" , identifier );
173185 log .info ("Container '{}' has stopped" , identifier );
174186 } catch (final InterruptedException interruptedException ) {
175- log .error ("Container '{}' was interrupted during the shutdown process. Doing a forceful shutdown that may eventually complete " , identifier );
187+ log .error ("Container '{}' was interrupted during the shutdown process." , identifier );
176188 } catch (RuntimeException runtimeException ) {
177189 log .error ("Unexpected error trying to start/stop the container" , runtimeException );
178190 }
@@ -199,7 +211,6 @@ private void processMessagesFromRetriever(final MessageBroker messageBroker,
199211 final MessageResolver messageResolver ,
200212 final ExecutorService brokerExecutorService ,
201213 final ExecutorService messageProcessingExecutorService ) throws InterruptedException {
202- log .info ("Container '{}' is beginning to process messages" , identifier );
203214 try {
204215 runUntilInterruption (brokerExecutorService , () -> messageBroker .processMessages (
205216 messageProcessingExecutorService ,
@@ -227,18 +238,15 @@ private void processExtraMessages(final MessageBroker messageBroker,
227238 final ExecutorService messageBrokerExecutorService ,
228239 final ExecutorService executorService ,
229240 final Queue <Message > messages ) throws InterruptedException {
230- if (!messages .isEmpty () && shouldProcessAnyExtraRetrievedMessagesOnShutdown ()) {
231- log .debug ("Container '{}' is processing {} extra messages before shutdown" , identifier , messages .size ());
232- try {
233- runUntilInterruption (messageBrokerExecutorService , () -> messageBroker .processMessages (
234- executorService ,
235- () -> !messages .isEmpty (),
236- () -> CompletableFuture .completedFuture (messages .poll ()),
237- message -> messageProcessor .processMessage (message , () -> messageResolver .resolveMessage (message ))
238- ));
239- } catch (final ExecutionException executionException ) {
240- log .error ("Exception thrown processing extra messages" , executionException .getCause ());
241- }
241+ try {
242+ runUntilInterruption (messageBrokerExecutorService , () -> messageBroker .processMessages (
243+ executorService ,
244+ () -> !messages .isEmpty (),
245+ () -> CompletableFuture .completedFuture (messages .poll ()),
246+ message -> messageProcessor .processMessage (message , () -> messageResolver .resolveMessage (message ))
247+ ));
248+ } catch (final ExecutionException executionException ) {
249+ log .error ("Exception thrown processing extra messages" , executionException .getCause ());
242250 }
243251 }
244252
@@ -281,15 +289,35 @@ private void runUntilInterruption(final ExecutorService executorService, final B
281289 * @throws InterruptedException if the thread was interrupted during this process
282290 */
283291 private void shutdownMessageProcessingThreads (final ExecutorService executorService ) throws InterruptedException {
284- log .debug ("Container '{}' is waiting for all message processing threads to finish..." , identifier );
285292 if (shouldInterruptMessageProcessingThreadsOnShutdown ()) {
293+ log .debug ("Container '{}' is interrupting and then waiting for all message processing threads to finish" , identifier );
286294 executorService .shutdownNow ();
287- log .debug ("Container '{}' interrupted the message processing threads" , identifier );
288295 } else {
296+ log .debug ("Container '{}' is waiting for all message processing threads to finish" , identifier );
289297 executorService .shutdown ();
290298 }
291299
292- executorService .awaitTermination (getMessageProcessingShutdownTimeoutInSeconds (), SECONDS );
300+ final int shutdownTimeoutInSeconds = getMessageProcessingShutdownTimeoutInSeconds ();
301+ final boolean messageProcessingTerminated = executorService .awaitTermination (shutdownTimeoutInSeconds , SECONDS );
302+ if (!messageProcessingTerminated ) {
303+ log .error ("Container '{}' did not shutdown MessageProcessor threads within {} seconds" , identifier , shutdownTimeoutInSeconds );
304+ }
305+ }
306+
307+ /**
308+ * Stop the message broker thread and wait for the configured amount of time to complete.
309+ *
310+ * @param executorService the executor service for the message broker
311+ * @throws InterruptedException if the thread was interrupted while waiting for the service to stop
312+ */
313+ private void shutdownMessageBroker (final ExecutorService executorService ) throws InterruptedException {
314+ executorService .shutdownNow ();
315+
316+ final int shutdownTimeoutInSeconds = getMessageBrokerShutdownTimeoutInSeconds ();
317+ final boolean terminationResult = executorService .awaitTermination (shutdownTimeoutInSeconds , SECONDS );
318+ if (!terminationResult ) {
319+ log .error ("Container '{}' did not shutdown MessageBroker within {} seconds" , getIdentifier (), shutdownTimeoutInSeconds );
320+ }
293321 }
294322
295323 /**
@@ -309,14 +337,12 @@ private BlockingRunnable startupMessageRetriever(final MessageRetriever messageR
309337 CompletableFuture .supplyAsync (messageRetriever ::run , executorService )
310338 .thenAccept (extraMessagesConsumer );
311339 return () -> {
312- log .info ("Shutting down MessageRetriever" );
313340 executorService .shutdownNow ();
314341
315- final boolean retrieverShutdown ;
316342 final int retrieverShutdownTimeoutInSeconds = getMessageRetrieverShutdownTimeoutInSeconds ();
317- retrieverShutdown = executorService .awaitTermination (retrieverShutdownTimeoutInSeconds , SECONDS );
343+ final boolean retrieverShutdown = executorService .awaitTermination (retrieverShutdownTimeoutInSeconds , SECONDS );
318344 if (!retrieverShutdown ) {
319- log .error ("MessageRetriever did not shutdown within {} seconds" , retrieverShutdownTimeoutInSeconds );
345+ log .error ("Container '{}' did not shutdown MessageRetriever within {} seconds" , getIdentifier () , retrieverShutdownTimeoutInSeconds );
320346 }
321347 };
322348 }
@@ -332,13 +358,12 @@ private BlockingRunnable startupMessageResolver(final MessageResolver messageRes
332358 final ExecutorService executorService = Executors .newSingleThreadExecutor (threadFactory (getIdentifier () + "-message-resolver" ));
333359 CompletableFuture .runAsync (messageResolver ::run , executorService );
334360 return () -> {
335- log .info ("Shutting down MessageResolver" );
336361 executorService .shutdownNow ();
337362
338363 final long messageResolverShutdownTimeInSeconds = getMessageResolverShutdownTimeoutInSeconds ();
339364 final boolean messageResolverShutdown = executorService .awaitTermination (getMessageResolverShutdownTimeoutInSeconds (), SECONDS );
340365 if (!messageResolverShutdown ) {
341- log .error ("MessageResolver did not shutdown within {} seconds" , messageResolverShutdownTimeInSeconds );
366+ log .error ("Container '{}' did not shutdown MessageResolver within {} seconds" , getIdentifier () , messageResolverShutdownTimeInSeconds );
342367 }
343368 };
344369 }
@@ -365,6 +390,19 @@ private int getMessageProcessingShutdownTimeoutInSeconds() {
365390 );
366391 }
367392
393+ /**
394+ * Get the amount of time in seconds that we should wait for the {@link MessageBroker} to shutdown when requested.
395+ *
396+ * @return the amount of time in seconds to wait for shutdown
397+ */
398+ private int getMessageBrokerShutdownTimeoutInSeconds () {
399+ return PropertyUtils .safelyGetPositiveOrZeroIntegerValue (
400+ "messageBrokerShutdownTimeoutInSeconds" ,
401+ properties ::getMessageBrokerShutdownTimeoutInSeconds ,
402+ DEFAULT_SHUTDOWN_TIME_IN_SECONDS
403+ );
404+ }
405+
368406 /**
369407 * Get the amount of time in seconds that we should wait for the {@link MessageRetriever} to shutdown when requested.
370408 *
@@ -385,7 +423,7 @@ private int getMessageRetrieverShutdownTimeoutInSeconds() {
385423 */
386424 private int getMessageResolverShutdownTimeoutInSeconds () {
387425 return PropertyUtils .safelyGetPositiveOrZeroIntegerValue (
388- "messageRetrieverShutdownTimeoutInSeconds " ,
426+ "messageResolverShutdownTimeoutInSeconds " ,
389427 properties ::getMessageResolverShutdownTimeoutInSeconds ,
390428 DEFAULT_SHUTDOWN_TIME_IN_SECONDS
391429 );
0 commit comments