BewareMyPower commented on issue #24894: URL: https://github.com/apache/pulsar/issues/24894#issuecomment-3450985038
The root cause is that Pulsar uses the configured `brokerShutdownTimeoutMs` to determine the 1st argument passed to `EventExecutorGroup#shutdownGracefully`. https://github.com/apache/pulsar/blob/7c6a4aae336a631e0b88998cf54c656c2f193ba4/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/BrokerService.java#L209-L211 https://github.com/apache/pulsar/blob/7c6a4aae336a631e0b88998cf54c656c2f193ba4/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/BrokerService.java#L964-L973 When `brokerShutdownTimeoutMs` is greater than 20000, the 1st argument will be 5000. This parameter represents the period to check if there was a new task executed since when the last task finished. See https://github.com/netty/netty/blob/6bb1a6bcae503423343b9155ac48b161f60368b5/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java#L785 ```java if (nanoTime - lastExecutionTime <= gracefulShutdownQuietPeriod) { // Check if any tasks were added to the queue every 100ms. // TODO: Change the behavior of takeTask() so that it returns on timeout. taskQueue.offer(WAKEUP_TASK); try { Thread.sleep(100); } catch (InterruptedException e) { // Ignore } return false; } ``` i.e. assuming the 1st argument is 5000, if the last task finished at `t` and `confirmShutdown` was called at `t + 1ms`, then it would sleep for 100 ms in a loop for at least 50 times so that the current time is greater than `t + 5000`. Here is a simple test to verify the behavior: ```java @Test public void test() { final SingleThreadEventExecutor executor = new DefaultEventExecutor(); executor.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread() + " " + System.currentTimeMillis() + " started"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new IllegalStateException(e); } System.out.println(Thread.currentThread() + " " + System.currentTimeMillis() + " finished"); } }); final long startNs = System.nanoTime(); executor.shutdownGracefully(5000, 10000, TimeUnit.MILLISECONDS).syncUninterruptibly(); final long elapsedMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); System.out.println(Thread.currentThread() + " " + System.currentTimeMillis() + " shutdown: " + elapsedMs + " ms"); } ``` Outputs: ``` Thread[defaultEventExecutor-1-1,5,main] 1761566989756 started Thread[defaultEventExecutor-1-1,5,main] 1761566990761 finished Thread[main,5,main] 1761566995846 shutdown: 6090 ms ``` Pulsar's `EventLoop` object created by `EventLoopUtils#newEventLoopGroup` uses `NioEventLoop` as the executor, which does not change the `confirmShutdown` and `shutdownGracefully` methods from the `SingleThreadEventExecutor` base class. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
