@@ -161,18 +161,30 @@ void runContainer() {
161
161
final Queue <Message > extraMessages = new LinkedList <>();
162
162
163
163
final BlockingRunnable shutdownMessageRetriever = startupMessageRetriever (messageRetriever , extraMessages ::addAll );
164
-
164
+ log . info ( "Container '{}' is beginning to process messages" , identifier );
165
165
processMessagesFromRetriever (messageBroker , messageRetriever , messageProcessor , messageResolver ,
166
166
messageBrokerExecutorService , messageProcessingExecutorService );
167
167
log .info ("Container '{}' is being shutdown" , identifier );
168
+ log .debug ("Container '{}' is shutting down MessageRetriever" , identifier );
168
169
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 );
171
177
shutdownMessageProcessingThreads (messageProcessingExecutorService );
178
+ log .debug ("Container '{}' has shutdown the MessageProcessor threads" , identifier );
179
+ log .debug ("Container '{}' is shutting down MessageResolver" , identifier );
172
180
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 );
173
185
log .info ("Container '{}' has stopped" , identifier );
174
186
} 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 );
176
188
} catch (RuntimeException runtimeException ) {
177
189
log .error ("Unexpected error trying to start/stop the container" , runtimeException );
178
190
}
@@ -199,7 +211,6 @@ private void processMessagesFromRetriever(final MessageBroker messageBroker,
199
211
final MessageResolver messageResolver ,
200
212
final ExecutorService brokerExecutorService ,
201
213
final ExecutorService messageProcessingExecutorService ) throws InterruptedException {
202
- log .info ("Container '{}' is beginning to process messages" , identifier );
203
214
try {
204
215
runUntilInterruption (brokerExecutorService , () -> messageBroker .processMessages (
205
216
messageProcessingExecutorService ,
@@ -227,18 +238,15 @@ private void processExtraMessages(final MessageBroker messageBroker,
227
238
final ExecutorService messageBrokerExecutorService ,
228
239
final ExecutorService executorService ,
229
240
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 ());
242
250
}
243
251
}
244
252
@@ -281,15 +289,35 @@ private void runUntilInterruption(final ExecutorService executorService, final B
281
289
* @throws InterruptedException if the thread was interrupted during this process
282
290
*/
283
291
private void shutdownMessageProcessingThreads (final ExecutorService executorService ) throws InterruptedException {
284
- log .debug ("Container '{}' is waiting for all message processing threads to finish..." , identifier );
285
292
if (shouldInterruptMessageProcessingThreadsOnShutdown ()) {
293
+ log .debug ("Container '{}' is interrupting and then waiting for all message processing threads to finish" , identifier );
286
294
executorService .shutdownNow ();
287
- log .debug ("Container '{}' interrupted the message processing threads" , identifier );
288
295
} else {
296
+ log .debug ("Container '{}' is waiting for all message processing threads to finish" , identifier );
289
297
executorService .shutdown ();
290
298
}
291
299
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
+ }
293
321
}
294
322
295
323
/**
@@ -309,14 +337,12 @@ private BlockingRunnable startupMessageRetriever(final MessageRetriever messageR
309
337
CompletableFuture .supplyAsync (messageRetriever ::run , executorService )
310
338
.thenAccept (extraMessagesConsumer );
311
339
return () -> {
312
- log .info ("Shutting down MessageRetriever" );
313
340
executorService .shutdownNow ();
314
341
315
- final boolean retrieverShutdown ;
316
342
final int retrieverShutdownTimeoutInSeconds = getMessageRetrieverShutdownTimeoutInSeconds ();
317
- retrieverShutdown = executorService .awaitTermination (retrieverShutdownTimeoutInSeconds , SECONDS );
343
+ final boolean retrieverShutdown = executorService .awaitTermination (retrieverShutdownTimeoutInSeconds , SECONDS );
318
344
if (!retrieverShutdown ) {
319
- log .error ("MessageRetriever did not shutdown within {} seconds" , retrieverShutdownTimeoutInSeconds );
345
+ log .error ("Container '{}' did not shutdown MessageRetriever within {} seconds" , getIdentifier () , retrieverShutdownTimeoutInSeconds );
320
346
}
321
347
};
322
348
}
@@ -332,13 +358,12 @@ private BlockingRunnable startupMessageResolver(final MessageResolver messageRes
332
358
final ExecutorService executorService = Executors .newSingleThreadExecutor (threadFactory (getIdentifier () + "-message-resolver" ));
333
359
CompletableFuture .runAsync (messageResolver ::run , executorService );
334
360
return () -> {
335
- log .info ("Shutting down MessageResolver" );
336
361
executorService .shutdownNow ();
337
362
338
363
final long messageResolverShutdownTimeInSeconds = getMessageResolverShutdownTimeoutInSeconds ();
339
364
final boolean messageResolverShutdown = executorService .awaitTermination (getMessageResolverShutdownTimeoutInSeconds (), SECONDS );
340
365
if (!messageResolverShutdown ) {
341
- log .error ("MessageResolver did not shutdown within {} seconds" , messageResolverShutdownTimeInSeconds );
366
+ log .error ("Container '{}' did not shutdown MessageResolver within {} seconds" , getIdentifier () , messageResolverShutdownTimeInSeconds );
342
367
}
343
368
};
344
369
}
@@ -365,6 +390,19 @@ private int getMessageProcessingShutdownTimeoutInSeconds() {
365
390
);
366
391
}
367
392
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
+
368
406
/**
369
407
* Get the amount of time in seconds that we should wait for the {@link MessageRetriever} to shutdown when requested.
370
408
*
@@ -385,7 +423,7 @@ private int getMessageRetrieverShutdownTimeoutInSeconds() {
385
423
*/
386
424
private int getMessageResolverShutdownTimeoutInSeconds () {
387
425
return PropertyUtils .safelyGetPositiveOrZeroIntegerValue (
388
- "messageRetrieverShutdownTimeoutInSeconds " ,
426
+ "messageResolverShutdownTimeoutInSeconds " ,
389
427
properties ::getMessageResolverShutdownTimeoutInSeconds ,
390
428
DEFAULT_SHUTDOWN_TIME_IN_SECONDS
391
429
);
0 commit comments