[tomcat] 01/02: Improve locking of utility executor

2023-05-10 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit ea9a80fe743fca86362a2184806941b655bd0088
Author: Mark Thomas 
AuthorDate: Thu May 4 11:41:57 2023 +0100

Improve locking of utility executor

Fixes some edge cases around calling setUtilityThreads() during stop
---
 java/org/apache/catalina/core/StandardServer.java | 51 +--
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index 8db5d8f05a..f7ac2d2e61 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -429,27 +429,30 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 return;
 }
 this.utilityThreads = utilityThreads;
-if (oldUtilityThreads != utilityThreads && utilityExecutor != null) {
-
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+synchronized (utilityExecutorLock) {
+if (oldUtilityThreads != utilityThreads && utilityExecutor != 
null) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+}
 }
 }
 
 
+/*
+ * Callers must be holding utilityExecutorLock
+ */
 private void reconfigureUtilityExecutor(int threads) {
-synchronized (utilityExecutorLock) {
-// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, 
only CorePoolSize is available
-if (utilityExecutor != null) {
-utilityExecutor.setCorePoolSize(threads);
-} else {
-ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
-new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
-scheduledThreadPoolExecutor.setKeepAliveTime(10, 
TimeUnit.SECONDS);
-scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
-
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-utilityExecutor = scheduledThreadPoolExecutor;
-utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
-utilityExecutor);
-}
+// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, only 
CorePoolSize is available
+if (utilityExecutor != null) {
+utilityExecutor.setCorePoolSize(threads);
+} else {
+ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
+new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
+scheduledThreadPoolExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
+scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
+
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+utilityExecutor = scheduledThreadPoolExecutor;
+utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
+utilityExecutor);
 }
 }
 
@@ -981,8 +984,10 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 super.initInternal();
 
     // Initialize utility executor
-reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
-register(utilityExecutor, "type=UtilityExecutor");
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+register(utilityExecutor, "type=UtilityExecutor");
+}
 
 // Register global String cache
 // Note although the cache is global, if there are multiple Servers
@@ -1042,10 +1047,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 
 unregister(onameStringCache);
 
-if (utilityExecutor != null) {
-utilityExecutor.shutdownNow();
-unregister("type=UtilityExecutor");
-utilityExecutor = null;
+synchronized (utilityExecutorLock) {
+if (utilityExecutor != null) {
+utilityExecutor.shutdownNow();
+unregister("type=UtilityExecutor");
+utilityExecutor = null;
+}
 }
 
 super.destroyInternal();


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-10 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit de6aacea433f28786329ac14f32d41a4d9951ebb
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

Move management of utility executor from init/destroy to start/stop
---
 java/org/apache/catalina/connector/Connector.java  | 14 ---
 java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
 java/org/apache/catalina/core/StandardServer.java  | 28 +++---
 .../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
 webapps/docs/changelog.xml |  5 
 5 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/connector/Connector.java 
b/java/org/apache/catalina/connector/Connector.java
index c504210b64..7339f961b2 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -982,9 +982,6 @@ public class Connector extends LifecycleMBeanBase {
 // Initialize adapter
 adapter = new CoyoteAdapter(this);
 protocolHandler.setAdapter(adapter);
-if (service != null) {
-
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
-}
 
 // Make sure parseBodyMethodsSet has a default
 if (null == parseBodyMethodsSet) {
@@ -1033,9 +1030,15 @@ public class Connector extends LifecycleMBeanBase {
 
 setState(LifecycleState.STARTING);
 
+// Configure the utility executor before starting the protocol handler
+if (protocolHandler != null && service != null) {
+
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
+}
+
 try {
 protocolHandler.start();
 } catch (Exception e) {
+// Includes NPE - protocolHandler will be null for invalid 
protocol if throwOnFailure is false
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStartFailed"), 
e);
 }
 }
@@ -1058,6 +1061,11 @@ public class Connector extends LifecycleMBeanBase {
 } catch (Exception e) {
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"), 
e);
 }
+
+    // Remove the utility executor once the protocol handler has been 
stopped
+if (protocolHandler != null) {
+protocolHandler.setUtilityExecutor(null);
+}
 }
 
 
diff --git a/java/org/apache/catalina/core/ContainerBase.java 
b/java/org/apache/catalina/core/ContainerBase.java
index 7c96f5de5e..c5bc5994a6 100644
--- a/java/org/apache/catalina/core/ContainerBase.java
+++ b/java/org/apache/catalina/core/ContainerBase.java
@@ -820,13 +820,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 }
 
 
-@Override
-protected void initInternal() throws LifecycleException {
-reconfigureStartStopExecutor(getStartStopThreads());
-super.initInternal();
-}
-
-
 private void reconfigureStartStopExecutor(int threads) {
 if (threads == 1) {
 // Use a fake executor
@@ -852,6 +845,8 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 @Override
 protected synchronized void startInternal() throws LifecycleException {
 
+reconfigureStartStopExecutor(getStartStopThreads());
+
 // Start our subordinate components, if any
 logger = null;
 getLogger();
@@ -958,6 +953,12 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 if (cluster instanceof Lifecycle) {
 ((Lifecycle) cluster).stop();
 }
+
+// If init fails, this may be null
+if (startStopExecutor != null) {
+startStopExecutor.shutdownNow();
+startStopExecutor = null;
+}
 }
 
 @Override
@@ -987,11 +988,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 parent.removeChild(this);
 }
 
-// If init fails, this may be null
-if (startStopExecutor != null) {
-startStopExecutor.shutdownNow();
-}
-
 super.destroyInternal();
 }
 
diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index f7ac2d2e61..00e70c8b48 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -909,6 +909,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 fireLifecycleEvent(CONFIGURE_START_EVENT, null);
 setState(LifecycleState.STARTING);
 
+    // Initialize utility executor
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecut

[tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-10 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 9c3e2c8148a513bcd2813761632988d82126df9d
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

Move management of utility executor from init/destroy to start/stop
---
 java/org/apache/catalina/connector/Connector.java  | 14 ---
 java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
 java/org/apache/catalina/core/StandardServer.java  | 28 +++---
 .../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
 webapps/docs/changelog.xml |  9 +++
 5 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/connector/Connector.java 
b/java/org/apache/catalina/connector/Connector.java
index f9893b992e..18e865e157 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -994,9 +994,6 @@ public class Connector extends LifecycleMBeanBase {
 // Initialize adapter
 adapter = new CoyoteAdapter(this);
 protocolHandler.setAdapter(adapter);
-if (service != null) {
-
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
-}
 
 // Make sure parseBodyMethodsSet has a default
 if (null == parseBodyMethodsSet) {
@@ -1037,9 +1034,15 @@ public class Connector extends LifecycleMBeanBase {
 
 setState(LifecycleState.STARTING);
 
+// Configure the utility executor before starting the protocol handler
+if (protocolHandler != null && service != null) {
+
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
+}
+
 try {
 protocolHandler.start();
 } catch (Exception e) {
+// Includes NPE - protocolHandler will be null for invalid 
protocol if throwOnFailure is false
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStartFailed"), 
e);
 }
 }
@@ -1062,6 +1065,11 @@ public class Connector extends LifecycleMBeanBase {
 } catch (Exception e) {
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"), 
e);
 }
+
+    // Remove the utility executor once the protocol handler has been 
stopped
+if (protocolHandler != null) {
+protocolHandler.setUtilityExecutor(null);
+}
 }
 
 
diff --git a/java/org/apache/catalina/core/ContainerBase.java 
b/java/org/apache/catalina/core/ContainerBase.java
index 7c96f5de5e..c5bc5994a6 100644
--- a/java/org/apache/catalina/core/ContainerBase.java
+++ b/java/org/apache/catalina/core/ContainerBase.java
@@ -820,13 +820,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 }
 
 
-@Override
-protected void initInternal() throws LifecycleException {
-reconfigureStartStopExecutor(getStartStopThreads());
-super.initInternal();
-}
-
-
 private void reconfigureStartStopExecutor(int threads) {
 if (threads == 1) {
 // Use a fake executor
@@ -852,6 +845,8 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 @Override
 protected synchronized void startInternal() throws LifecycleException {
 
+reconfigureStartStopExecutor(getStartStopThreads());
+
 // Start our subordinate components, if any
 logger = null;
 getLogger();
@@ -958,6 +953,12 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 if (cluster instanceof Lifecycle) {
 ((Lifecycle) cluster).stop();
 }
+
+// If init fails, this may be null
+if (startStopExecutor != null) {
+startStopExecutor.shutdownNow();
+startStopExecutor = null;
+}
 }
 
 @Override
@@ -987,11 +988,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 parent.removeChild(this);
 }
 
-// If init fails, this may be null
-if (startStopExecutor != null) {
-startStopExecutor.shutdownNow();
-}
-
 super.destroyInternal();
 }
 
diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index 227784dbb3..5459131810 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -905,6 +905,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 fireLifecycleEvent(CONFIGURE_START_EVENT, null);
 setState(LifecycleState.STARTING);
 
+    // Initialize utility executor
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecut

[tomcat] 01/02: Improve locking of utility executor

2023-05-10 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 17b76c618145b6d431ade2d1844a65bf04f9ece7
Author: Mark Thomas 
AuthorDate: Thu May 4 11:41:57 2023 +0100

Improve locking of utility executor

Fixes some edge cases around calling setUtilityThreads() during stop
---
 java/org/apache/catalina/core/StandardServer.java | 51 +--
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index 5f4637153b..227784dbb3 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -425,27 +425,30 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 return;
 }
 this.utilityThreads = utilityThreads;
-if (oldUtilityThreads != utilityThreads && utilityExecutor != null) {
-
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+synchronized (utilityExecutorLock) {
+if (oldUtilityThreads != utilityThreads && utilityExecutor != 
null) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+}
 }
 }
 
 
+/*
+ * Callers must be holding utilityExecutorLock
+ */
 private void reconfigureUtilityExecutor(int threads) {
-synchronized (utilityExecutorLock) {
-// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, 
only CorePoolSize is available
-if (utilityExecutor != null) {
-utilityExecutor.setCorePoolSize(threads);
-} else {
-ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
-new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
-scheduledThreadPoolExecutor.setKeepAliveTime(10, 
TimeUnit.SECONDS);
-scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
-
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-utilityExecutor = scheduledThreadPoolExecutor;
-utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
-utilityExecutor);
-}
+// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, only 
CorePoolSize is available
+if (utilityExecutor != null) {
+utilityExecutor.setCorePoolSize(threads);
+} else {
+ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
+new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
+scheduledThreadPoolExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
+scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
+
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+utilityExecutor = scheduledThreadPoolExecutor;
+utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
+utilityExecutor);
 }
 }
 
@@ -977,8 +980,10 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 super.initInternal();
 
     // Initialize utility executor
-reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
-register(utilityExecutor, "type=UtilityExecutor");
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+register(utilityExecutor, "type=UtilityExecutor");
+}
 
 // Register global String cache
 // Note although the cache is global, if there are multiple Servers
@@ -1013,10 +1018,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 
 unregister(onameStringCache);
 
-if (utilityExecutor != null) {
-utilityExecutor.shutdownNow();
-unregister("type=UtilityExecutor");
-utilityExecutor = null;
+synchronized (utilityExecutorLock) {
+if (utilityExecutor != null) {
+utilityExecutor.shutdownNow();
+unregister("type=UtilityExecutor");
+utilityExecutor = null;
+}
 }
 
 super.destroyInternal();


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-05 Thread Mark Thomas

On 05/05/2023 13:17, Han Li wrote:




On May 5, 2023, at 18:42, Mark Thomas  wrote:

On 05/05/2023 04:21, Han Li wrote:

On May 4, 2023, at 21:41, ma...@apache.org wrote:

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

Move management of utility executor from init/destroy to start/stop
---
java/org/apache/catalina/connector/Connector.java | 13 +++---
java/org/apache/catalina/core/ContainerBase.java | 20 +++-
java/org/apache/catalina/core/StandardServer.java | 28 +++---
.../apache/catalina/ha/tcp/SimpleTcpCluster.java | 5 +++-
webapps/docs/changelog.xml | 5 
5 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/connector/Connector.java 
b/java/org/apache/catalina/connector/Connector.java
index c9200e20ca..dac7fdd642 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
// Initialize adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
- if (service != null) {
- protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
- }

// Make sure parseBodyMethodsSet has a default
if (null == parseBodyMethodsSet) {
@@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {

setState(LifecycleState.STARTING);

+ // Configure the utility executor before starting the protocol handler
+ if (service != null) {
+ protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());

According to check logic at line 1027, the protocalHandler may be null, so need 
NPE check.


I'm not convinced that check is necessary given the call to 
protocalHandler.start() just below. I need to look into this more to see why 
the null check is there.


I have also looked into this and found which related to 
org.apache.catalina.connector.TestConnector#doTestInvalidProtocol.
The reason that why this has three conditions:
1. The protocol is invalid
2. The thorwOnFailure has been set false

2) lead the null check in initInternal method has invalid and go on to 
startInternal.


Thanks. That is helpful. I'll add some null checks for the utility 
executor calls.


Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-05 Thread Han Li


> On May 5, 2023, at 18:42, Mark Thomas  wrote:
> 
> On 05/05/2023 04:21, Han Li wrote:
>>> On May 4, 2023, at 21:41, ma...@apache.org wrote:
>>> 
>>> This is an automated email from the ASF dual-hosted git repository.
>>> 
>>> markt pushed a commit to branch main
>>> in repository https://gitbox.apache.org/repos/asf/tomcat.git
>>> 
>>> commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
>>> Author: Mark Thomas 
>>> AuthorDate: Thu May 4 14:41:01 2023 +0100
>>> 
>>> Move management of utility executor from init/destroy to start/stop
>>> ---
>>> java/org/apache/catalina/connector/Connector.java | 13 +++---
>>> java/org/apache/catalina/core/ContainerBase.java | 20 +++-
>>> java/org/apache/catalina/core/StandardServer.java | 28 
>>> +++---
>>> .../apache/catalina/ha/tcp/SimpleTcpCluster.java | 5 +++-
>>> webapps/docs/changelog.xml | 5 
>>> 5 files changed, 41 insertions(+), 30 deletions(-)
>>> 
>>> diff --git a/java/org/apache/catalina/connector/Connector.java 
>>> b/java/org/apache/catalina/connector/Connector.java
>>> index c9200e20ca..dac7fdd642 100644
>>> --- a/java/org/apache/catalina/connector/Connector.java
>>> +++ b/java/org/apache/catalina/connector/Connector.java
>>> @@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
>>> // Initialize adapter
>>> adapter = new CoyoteAdapter(this);
>>> protocolHandler.setAdapter(adapter);
>>> - if (service != null) {
>>> - 
>>> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
>>> - }
>>> 
>>> // Make sure parseBodyMethodsSet has a default
>>> if (null == parseBodyMethodsSet) {
>>> @@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {
>>> 
>>> setState(LifecycleState.STARTING);
>>> 
>>> + // Configure the utility executor before starting the protocol handler
>>> + if (service != null) {
>>> + 
>>> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
>> According to check logic at line 1027, the protocalHandler may be null, so 
>> need NPE check.
> 
> I'm not convinced that check is necessary given the call to 
> protocalHandler.start() just below. I need to look into this more to see why 
> the null check is there.

I have also looked into this and found which related to 
org.apache.catalina.connector.TestConnector#doTestInvalidProtocol.
The reason that why this has three conditions:
1. The protocol is invalid
2. The thorwOnFailure has been set false

2) lead the null check in initInternal method has invalid and go on to 
startInternal.


Han

> 
>>> + }
>>> +
>>> try {
>>> protocolHandler.start();
>>> } catch (Exception e) {
>>> @@ -1060,6 +1062,11 @@ public class Connector extends LifecycleMBeanBase {
>>> } catch (Exception e) {
>>> throw new 
>>> LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"),
>>>  e);
>>> }
>>> +
>>> + // Remove the utility executor once the protocol handler has been stopped
>>> + if (service != null) {
>>> + protocolHandler.setUtilityExecutor(null);
>> Same as above.
> 
> I agree on this one.
> 
> Mark
> 
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org 
> <mailto:dev-unsubscr...@tomcat.apache.org>
> For additional commands, e-mail: dev-h...@tomcat.apache.org 
> <mailto:dev-h...@tomcat.apache.org>


Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-05 Thread koteswara Rao Gundapaneni
Hi Team ,


Management of start and stop might be arrested


Regards
Koti

On Thu, 4 May 2023, 19:12 ,  wrote:

> This is an automated email from the ASF dual-hosted git repository.
>
> markt pushed a commit to branch main
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
>
> commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
> Author: Mark Thomas 
> AuthorDate: Thu May 4 14:41:01 2023 +0100
>
>     Move management of utility executor from init/destroy to start/stop
> ---
>  java/org/apache/catalina/connector/Connector.java  | 13 +++---
>  java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
>  java/org/apache/catalina/core/StandardServer.java  | 28
> +++---
>  .../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
>  webapps/docs/changelog.xml |  5 
>  5 files changed, 41 insertions(+), 30 deletions(-)
>
> diff --git a/java/org/apache/catalina/connector/Connector.java
> b/java/org/apache/catalina/connector/Connector.java
> index c9200e20ca..dac7fdd642 100644
> --- a/java/org/apache/catalina/connector/Connector.java
> +++ b/java/org/apache/catalina/connector/Connector.java
> @@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
>  // Initialize adapter
>  adapter = new CoyoteAdapter(this);
>  protocolHandler.setAdapter(adapter);
> -if (service != null) {
> -
> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
> -}
>
>  // Make sure parseBodyMethodsSet has a default
>  if (null == parseBodyMethodsSet) {
> @@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {
>
>  setState(LifecycleState.STARTING);
>
> +// Configure the utility executor before starting the protocol
> handler
> +if (service != null) {
> +
> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
> +}
> +
>  try {
>  protocolHandler.start();
>  } catch (Exception e) {
> @@ -1060,6 +1062,11 @@ public class Connector extends LifecycleMBeanBase {
>  } catch (Exception e) {
>      throw new
> LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"),
> e);
>  }
> +
> +// Remove the utility executor once the protocol handler has been
> stopped
> +if (service != null) {
> +protocolHandler.setUtilityExecutor(null);
> +}
>  }
>
>
> diff --git a/java/org/apache/catalina/core/ContainerBase.java
> b/java/org/apache/catalina/core/ContainerBase.java
> index 784c9032ef..a7e7c69a4a 100644
> --- a/java/org/apache/catalina/core/ContainerBase.java
> +++ b/java/org/apache/catalina/core/ContainerBase.java
> @@ -787,13 +787,6 @@ public abstract class ContainerBase extends
> LifecycleMBeanBase implements Contai
>  }
>
>
> -@Override
> -protected void initInternal() throws LifecycleException {
> -reconfigureStartStopExecutor(getStartStopThreads());
> -super.initInternal();
> -}
> -
> -
>  private void reconfigureStartStopExecutor(int threads) {
>  if (threads == 1) {
>  // Use a fake executor
> @@ -819,6 +812,8 @@ public abstract class ContainerBase extends
> LifecycleMBeanBase implements Contai
>  @Override
>  protected synchronized void startInternal() throws LifecycleException
> {
>
> +reconfigureStartStopExecutor(getStartStopThreads());
> +
>  // Start our subordinate components, if any
>  logger = null;
>  getLogger();
> @@ -925,6 +920,12 @@ public abstract class ContainerBase extends
> LifecycleMBeanBase implements Contai
>  if (cluster instanceof Lifecycle) {
>  ((Lifecycle) cluster).stop();
>  }
> +
> +// If init fails, this may be null
> +if (startStopExecutor != null) {
> +startStopExecutor.shutdownNow();
> +startStopExecutor = null;
> +}
>  }
>
>  @Override
> @@ -954,11 +955,6 @@ public abstract class ContainerBase extends
> LifecycleMBeanBase implements Contai
>  parent.removeChild(this);
>  }
>
> -// If init fails, this may be null
> -if (startStopExecutor != null) {
> -startStopExecutor.shutdownNow();
> -}
> -
>  super.destroyInternal();
>  }
>
> diff --git a/java/org/apache/catalina/core/StandardServer.java
> b/java/org/apache/catalina/core/StandardServer.java
> index 80b5026fed..a4383f2503 100644
> --- a/java/org/apache/catalina/core/StandardServer.java
> +

Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-05 Thread Mark Thomas

On 05/05/2023 04:21, Han Li wrote:




On May 4, 2023, at 21:41, ma...@apache.org wrote:

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

Move management of utility executor from init/destroy to start/stop
---
java/org/apache/catalina/connector/Connector.java  | 13 +++---
java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
java/org/apache/catalina/core/StandardServer.java  | 28 +++---
.../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
webapps/docs/changelog.xml |  5 
5 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/connector/Connector.java 
b/java/org/apache/catalina/connector/Connector.java
index c9200e20ca..dac7fdd642 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
 // Initialize adapter
 adapter = new CoyoteAdapter(this);
 protocolHandler.setAdapter(adapter);
-if (service != null) {
-
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
-}

 // Make sure parseBodyMethodsSet has a default
 if (null == parseBodyMethodsSet) {
@@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {

 setState(LifecycleState.STARTING);

+// Configure the utility executor before starting the protocol handler
+if (service != null) {
+
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());


According to check logic at line 1027,  the protocalHandler may be null, so 
need NPE check.


I'm not convinced that check is necessary given the call to 
protocalHandler.start() just below. I need to look into this more to see 
why the null check is there.



+}
+
 try {
 protocolHandler.start();
 } catch (Exception e) {
@@ -1060,6 +1062,11 @@ public class Connector extends LifecycleMBeanBase {
 } catch (Exception e) {
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"), 
e);
 }
+
+// Remove the utility executor once the protocol handler has been 
stopped
+if (service != null) {
+protocolHandler.setUtilityExecutor(null);

Same as above.


I agree on this one.

Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-04 Thread Han Li



> On May 4, 2023, at 21:41, ma...@apache.org wrote:
> 
> This is an automated email from the ASF dual-hosted git repository.
> 
> markt pushed a commit to branch main
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
> 
> commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
> Author: Mark Thomas 
> AuthorDate: Thu May 4 14:41:01 2023 +0100
> 
>    Move management of utility executor from init/destroy to start/stop
> ---
> java/org/apache/catalina/connector/Connector.java  | 13 +++---
> java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
> java/org/apache/catalina/core/StandardServer.java  | 28 +++---
> .../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
> webapps/docs/changelog.xml |  5 
> 5 files changed, 41 insertions(+), 30 deletions(-)
> 
> diff --git a/java/org/apache/catalina/connector/Connector.java 
> b/java/org/apache/catalina/connector/Connector.java
> index c9200e20ca..dac7fdd642 100644
> --- a/java/org/apache/catalina/connector/Connector.java
> +++ b/java/org/apache/catalina/connector/Connector.java
> @@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
> // Initialize adapter
> adapter = new CoyoteAdapter(this);
> protocolHandler.setAdapter(adapter);
> -if (service != null) {
> -
> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
> -}
> 
> // Make sure parseBodyMethodsSet has a default
> if (null == parseBodyMethodsSet) {
> @@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {
> 
> setState(LifecycleState.STARTING);
> 
> +// Configure the utility executor before starting the protocol 
> handler
> +if (service != null) {
> +
> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());

According to check logic at line 1027,  the protocalHandler may be null, so 
need NPE check.
> +}
> +
> try {
> protocolHandler.start();
> } catch (Exception e) {
> @@ -1060,6 +1062,11 @@ public class Connector extends LifecycleMBeanBase {
> } catch (Exception e) {
> throw new 
> LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"), 
> e);
> }
> +
> +// Remove the utility executor once the protocol handler has been 
> stopped
> +if (service != null) {
> +protocolHandler.setUtilityExecutor(null);
Same as above.

Han
> +}
> }
> 
> 
> diff --git a/java/org/apache/catalina/core/ContainerBase.java 
> b/java/org/apache/catalina/core/ContainerBase.java
> index 784c9032ef..a7e7c69a4a 100644
> --- a/java/org/apache/catalina/core/ContainerBase.java
> +++ b/java/org/apache/catalina/core/ContainerBase.java
> @@ -787,13 +787,6 @@ public abstract class ContainerBase extends 
> LifecycleMBeanBase implements Contai
> }
> 
> 
> -@Override
> -protected void initInternal() throws LifecycleException {
> -reconfigureStartStopExecutor(getStartStopThreads());
> -super.initInternal();
> -}
> -
> -
> private void reconfigureStartStopExecutor(int threads) {
> if (threads == 1) {
> // Use a fake executor
> @@ -819,6 +812,8 @@ public abstract class ContainerBase extends 
> LifecycleMBeanBase implements Contai
> @Override
> protected synchronized void startInternal() throws LifecycleException {
> 
> +reconfigureStartStopExecutor(getStartStopThreads());
> +
> // Start our subordinate components, if any
> logger = null;
> getLogger();
> @@ -925,6 +920,12 @@ public abstract class ContainerBase extends 
> LifecycleMBeanBase implements Contai
> if (cluster instanceof Lifecycle) {
> ((Lifecycle) cluster).stop();
> }
> +
> +// If init fails, this may be null
> +if (startStopExecutor != null) {
> +startStopExecutor.shutdownNow();
> +startStopExecutor = null;
> +}
> }
> 
> @Override
> @@ -954,11 +955,6 @@ public abstract class ContainerBase extends 
> LifecycleMBeanBase implements Contai
> parent.removeChild(this);
> }
> 
> -// If init fails, this may be null
> -if (startStopExecutor != null) {
> -startStopExecutor.shutdownNow();
> -}
> -
> super.destroyInternal();
> }
> 
> diff --git a/java/org/apache/catalina/core/StandardServer.java 
> b/java/org/apache/catalina/core/StandardServer.java
> index 80b5026fed..a438

Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-04 Thread Rémy Maucherat
On Thu, May 4, 2023 at 3:46 PM Mark Thomas  wrote:
>
> On 04/05/2023 14:41, ma...@apache.org wrote:
> > This is an automated email from the ASF dual-hosted git repository.
> >
> > markt pushed a commit to branch main
> > in repository https://gitbox.apache.org/repos/asf/tomcat.git
> >
> > commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
> > Author: Mark Thomas 
> > AuthorDate: Thu May 4 14:41:01 2023 +0100
> >
> >  Move management of utility executor from init/destroy to start/stop
>
> My plan is to back-port this to earlier versions once the May releases
> have been tagged.

Thanks ;)

Rémy

> Mark
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: [tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-04 Thread Mark Thomas

On 04/05/2023 14:41, ma...@apache.org wrote:

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

 Move management of utility executor from init/destroy to start/stop


My plan is to back-port this to earlier versions once the May releases 
have been tagged.


Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] 02/02: Move management of utility executor from init/destroy to start/stop

2023-05-04 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4b097bf2e9075e9e2949ec5aa410cba3c2b85374
Author: Mark Thomas 
AuthorDate: Thu May 4 14:41:01 2023 +0100

Move management of utility executor from init/destroy to start/stop
---
 java/org/apache/catalina/connector/Connector.java  | 13 +++---
 java/org/apache/catalina/core/ContainerBase.java   | 20 +++-
 java/org/apache/catalina/core/StandardServer.java  | 28 +++---
 .../apache/catalina/ha/tcp/SimpleTcpCluster.java   |  5 +++-
 webapps/docs/changelog.xml |  5 
 5 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/connector/Connector.java 
b/java/org/apache/catalina/connector/Connector.java
index c9200e20ca..dac7fdd642 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -992,9 +992,6 @@ public class Connector extends LifecycleMBeanBase {
 // Initialize adapter
 adapter = new CoyoteAdapter(this);
 protocolHandler.setAdapter(adapter);
-if (service != null) {
-
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
-}
 
 // Make sure parseBodyMethodsSet has a default
 if (null == parseBodyMethodsSet) {
@@ -1035,6 +1032,11 @@ public class Connector extends LifecycleMBeanBase {
 
 setState(LifecycleState.STARTING);
 
+// Configure the utility executor before starting the protocol handler
+if (service != null) {
+
protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
+}
+
 try {
 protocolHandler.start();
 } catch (Exception e) {
@@ -1060,6 +1062,11 @@ public class Connector extends LifecycleMBeanBase {
 } catch (Exception e) {
 throw new 
LifecycleException(sm.getString("coyoteConnector.protocolHandlerStopFailed"), 
e);
 }
+
+// Remove the utility executor once the protocol handler has been 
stopped
+if (service != null) {
+protocolHandler.setUtilityExecutor(null);
+}
 }
 
 
diff --git a/java/org/apache/catalina/core/ContainerBase.java 
b/java/org/apache/catalina/core/ContainerBase.java
index 784c9032ef..a7e7c69a4a 100644
--- a/java/org/apache/catalina/core/ContainerBase.java
+++ b/java/org/apache/catalina/core/ContainerBase.java
@@ -787,13 +787,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 }
 
 
-@Override
-protected void initInternal() throws LifecycleException {
-reconfigureStartStopExecutor(getStartStopThreads());
-super.initInternal();
-}
-
-
 private void reconfigureStartStopExecutor(int threads) {
 if (threads == 1) {
 // Use a fake executor
@@ -819,6 +812,8 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 @Override
 protected synchronized void startInternal() throws LifecycleException {
 
+reconfigureStartStopExecutor(getStartStopThreads());
+
 // Start our subordinate components, if any
 logger = null;
 getLogger();
@@ -925,6 +920,12 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 if (cluster instanceof Lifecycle) {
 ((Lifecycle) cluster).stop();
 }
+
+// If init fails, this may be null
+if (startStopExecutor != null) {
+startStopExecutor.shutdownNow();
+startStopExecutor = null;
+}
 }
 
 @Override
@@ -954,11 +955,6 @@ public abstract class ContainerBase extends 
LifecycleMBeanBase implements Contai
 parent.removeChild(this);
 }
 
-// If init fails, this may be null
-if (startStopExecutor != null) {
-startStopExecutor.shutdownNow();
-}
-
 super.destroyInternal();
 }
 
diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index 80b5026fed..a4383f2503 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -901,6 +901,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 fireLifecycleEvent(CONFIGURE_START_EVENT, null);
 setState(LifecycleState.STARTING);
 
+// Initialize utility executor
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+register(utilityExecutor, "type=UtilityExecutor");
+}
+
 globalNamingResources.start();
 
 // Start our defined Services
@@ -961,6 +967,14 @@ public final class StandardServer extends 
LifecycleMBeanBa

[tomcat] 01/02: Improve locking of utility executor

2023-05-04 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 71032f7b2906ef85b6402b986483d9715bd65e63
Author: Mark Thomas 
AuthorDate: Thu May 4 11:41:57 2023 +0100

Improve locking of utility executor

Fixes some edge cases around calling setUtilityThreads() during stop
---
 java/org/apache/catalina/core/StandardServer.java | 51 +--
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/core/StandardServer.java 
b/java/org/apache/catalina/core/StandardServer.java
index 09a223fa80..80b5026fed 100644
--- a/java/org/apache/catalina/core/StandardServer.java
+++ b/java/org/apache/catalina/core/StandardServer.java
@@ -424,27 +424,30 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 return;
 }
 this.utilityThreads = utilityThreads;
-if (oldUtilityThreads != utilityThreads && utilityExecutor != null) {
-
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+synchronized (utilityExecutorLock) {
+if (oldUtilityThreads != utilityThreads && utilityExecutor != 
null) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+}
 }
 }
 
 
+/*
+ * Callers must be holding utilityExecutorLock
+ */
 private void reconfigureUtilityExecutor(int threads) {
-synchronized (utilityExecutorLock) {
-// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, 
only CorePoolSize is available
-if (utilityExecutor != null) {
-utilityExecutor.setCorePoolSize(threads);
-} else {
-ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
-new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
-scheduledThreadPoolExecutor.setKeepAliveTime(10, 
TimeUnit.SECONDS);
-scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
-
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-utilityExecutor = scheduledThreadPoolExecutor;
-utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
-utilityExecutor);
-}
+// The ScheduledThreadPoolExecutor doesn't use MaximumPoolSize, only 
CorePoolSize is available
+if (utilityExecutor != null) {
+utilityExecutor.setCorePoolSize(threads);
+} else {
+ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new 
ScheduledThreadPoolExecutor(threads,
+new TaskThreadFactory("Catalina-utility-", 
utilityThreadsAsDaemon, Thread.MIN_PRIORITY));
+scheduledThreadPoolExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
+scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
+
scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+utilityExecutor = scheduledThreadPoolExecutor;
+utilityExecutorWrapper = new 
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor(
+utilityExecutor);
 }
 }
 
@@ -973,8 +976,10 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 super.initInternal();
 
     // Initialize utility executor
-reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
-register(utilityExecutor, "type=UtilityExecutor");
+synchronized (utilityExecutorLock) {
+
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
+register(utilityExecutor, "type=UtilityExecutor");
+}
 
 // Register global String cache
 // Note although the cache is global, if there are multiple Servers
@@ -1009,10 +1014,12 @@ public final class StandardServer extends 
LifecycleMBeanBase implements Server {
 
 unregister(onameStringCache);
 
-if (utilityExecutor != null) {
-utilityExecutor.shutdownNow();
-unregister("type=UtilityExecutor");
-utilityExecutor = null;
+synchronized (utilityExecutorLock) {
+if (utilityExecutor != null) {
+utilityExecutor.shutdownNow();
+unregister("type=UtilityExecutor");
+utilityExecutor = null;
+}
 }
 
 super.destroyInternal();


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread Rémy Maucherat
On Fri, Apr 28, 2023 at 3:35 PM Konstantin Kolinko
 wrote:
>
> пт, 28 апр. 2023 г. в 16:21, Konstantin Kolinko :
> >
> > чт, 27 апр. 2023 г. в 19:34, Mark Thomas :
> > >
> > > Hi all,
> > >
> > > As part of a discussion around a Spring Boot issue [1], the question has
> > > been raised whether there is merit in moving the Utility executor
> > > start/stop from StandardServer init/destroy to start/stop.
> > >
> > > I've looked at the code and I don't see any uses of the Executor until
> > > sub-components are in the start phase (there is a little copying of
> > > references that might need to move) so I think the change is doable.
> > >
> > > The main advantage is that in the embedded scenario where there might be
> > > a long series of start / stop / start / stop etc, shutting down the
> > > executor on stop should avoid issues where executor tasks are not
> > > shutdown correctly. My brief code review suggested that Tomcat does this
> > > correctly but the executor is also exposed to application code.
> > >
> > > Thoughts?
> > >
> > > Mark
> > >
> > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> >
> > +1.
> >
> > It sounds reasonable, and thinking about Tomcat being started by
> > Commons Daemon jsvc, I think that init() should not be used to start
> > utility threads.
> >
> > If it causes a regression (I mean, if something really needs to be
> > done at init() time), one may implement a Listener.
>
> Looking at when a Connector starts its pool of threads,
>
> o.a.c.connector.Connector.initInternal() does
>
> // Initialize adapter
> adapter = new CoyoteAdapter(this);
> protocolHandler.setAdapter(adapter);
> if (service != null) {
> 
> protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
> }
>
> So it also needs a change.

I noted down that item already (simply looking at all the
getUtilityExecutor calls, basically), it's simply that the pool is
available in init, so it's set up in the endpoint at that time because
"why not", but it's not actually used yet.

Rémy

>
> Best regards,
> Konstantin Kolinko
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread Konstantin Kolinko
пт, 28 апр. 2023 г. в 16:21, Konstantin Kolinko :
>
> чт, 27 апр. 2023 г. в 19:34, Mark Thomas :
> >
> > Hi all,
> >
> > As part of a discussion around a Spring Boot issue [1], the question has
> > been raised whether there is merit in moving the Utility executor
> > start/stop from StandardServer init/destroy to start/stop.
> >
> > I've looked at the code and I don't see any uses of the Executor until
> > sub-components are in the start phase (there is a little copying of
> > references that might need to move) so I think the change is doable.
> >
> > The main advantage is that in the embedded scenario where there might be
> > a long series of start / stop / start / stop etc, shutting down the
> > executor on stop should avoid issues where executor tasks are not
> > shutdown correctly. My brief code review suggested that Tomcat does this
> > correctly but the executor is also exposed to application code.
> >
> > Thoughts?
> >
> > Mark
> >
> > [1] https://github.com/spring-projects/spring-boot/issues/34955
>
> +1.
>
> It sounds reasonable, and thinking about Tomcat being started by
> Commons Daemon jsvc, I think that init() should not be used to start
> utility threads.
>
> If it causes a regression (I mean, if something really needs to be
> done at init() time), one may implement a Listener.

Looking at when a Connector starts its pool of threads,

o.a.c.connector.Connector.initInternal() does

// Initialize adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
if (service != null) {

protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
}

So it also needs a change.

Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread Konstantin Kolinko
чт, 27 апр. 2023 г. в 19:34, Mark Thomas :
>
> Hi all,
>
> As part of a discussion around a Spring Boot issue [1], the question has
> been raised whether there is merit in moving the Utility executor
> start/stop from StandardServer init/destroy to start/stop.
>
> I've looked at the code and I don't see any uses of the Executor until
> sub-components are in the start phase (there is a little copying of
> references that might need to move) so I think the change is doable.
>
> The main advantage is that in the embedded scenario where there might be
> a long series of start / stop / start / stop etc, shutting down the
> executor on stop should avoid issues where executor tasks are not
> shutdown correctly. My brief code review suggested that Tomcat does this
> correctly but the executor is also exposed to application code.
>
> Thoughts?
>
> Mark
>
> [1] https://github.com/spring-projects/spring-boot/issues/34955

+1.

It sounds reasonable, and thinking about Tomcat being started by
Commons Daemon jsvc, I think that init() should not be used to start
utility threads.

If it causes a regression (I mean, if something really needs to be
done at init() time), one may implement a Listener.

Best regards,
Konstantin Kolinko

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread koteswara Rao Gundapaneni
Hi Team,


Its quite awesome discussion to easy the tomcat as proc

I will say it's background compatible since then we added background active
element
StartStop both are in the hand of separate module

Spring Boot is already doing this as tomcat working as in background so it
will boost tomcat will gain the full moment of both are added

Regards
Koti

On Fri, 28 Apr 2023, 15:25 Rémy Maucherat,  wrote:

> On Fri, Apr 28, 2023 at 9:02 AM Romain Manni-Bucau
>  wrote:
> >
> > Le ven. 28 avr. 2023 à 08:36, Rémy Maucherat  a écrit :
> >
> > > On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
> > >  wrote:
> > > >
> > > > Hi
> > > >
> > > > Guess this utility should be there very early so before other
> > > starts/stops
> > > > sounds good but ultimately init/destroy is better since it avoids to
> > > create
> > > > custom utility threads in subcomponents init/destroy (more destroy
> for
> > > real
> > > > cases I think, not sure for init).
> > >
> > > The Server starts first and stops last, so it seems it will be fine. I
> > > don't quite see why it is a good idea to do utility tasks in init or
> > > destroyed (they should happen in start or stop).
> > > Right now the only item which needs to change is that the connector
> > > endpoint gets it on init. The other components were using it on start.
> > >
> >
> > Still in the spirit of being "stable" in terms of threads and avoiding to
> > create instances per components (which makes the machine under stress, in
> > particular when combined with colocalised deployments - k8s style or just
> > multiple processes locally.
> > The destroy usage I saw was mainly to push (broadcast) metrics captured
> > between stop and destroy by valves - but can ack it is a bit particular
> so
> > can not need something specific.
>
> We are talking about a Server.stop/start here, this is a very
> expensive process (TLS configs, and so on), and I don't understand why
> it would be a good idea to allow background tasks of subcomponents to
> keep running.
>
> > That said I'm not sure it fixes the spring-boot issue at all.
>
> Remy
>
> >
> > >
> > > Remy
> > >
> > > > What about getting it injected from the context and ignoring its
> > > lifecycle
> > > > ("external" notion)? Will keep it globally usable and integrate
> smoothly
> > > > with any env.
> > > >
> > > >
> > > > Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
> > > >
> > > > >
> > > > >
> > > > > > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> > > > > >
> > > > > > Hi all,
> > > > > >
> > > > > > As part of a discussion around a Spring Boot issue [1], the
> question
> > > has
> > > > > been raised whether there is merit in moving the Utility executor
> > > > > start/stop from StandardServer init/destroy to start/stop.
> > > > > >
> > > > > > I've looked at the code and I don't see any uses of the Executor
> > > until
> > > > > sub-components are in the start phase (there is a little copying of
> > > > > references that might need to move) so I think the change is
> doable.
> > > > >
> > > > > Maybe ContainerBase#startStopExecutor also need same operation
> above?
> > > > >
> > > > > >
> > > > > > The main advantage is that in the embedded scenario where there
> > > might be
> > > > > a long series of start / stop / start / stop etc, shutting down the
> > > > > executor on stop should avoid issues where executor tasks are not
> > > shutdown
> > > > > correctly. My brief code review suggested that Tomcat does this
> > > correctly
> > > > > but the executor is also exposed to application code.
> > > > > >
> > > > > > Thoughts?
> > > > > + 1
> > > > >
> > > > > >
> > > > > > Mark
> > > > > >
> > > > > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> > > > > >
> > > > > >
> -
> > > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > > > >
> > > > >
> > > > >
> > > > >
> -
> > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > > >
> > > > >
> > >
> > > -
> > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > >
> > >
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Utility Executor

2023-04-28 Thread Romain Manni-Bucau
Le ven. 28 avr. 2023 à 11:55, Rémy Maucherat  a écrit :

> On Fri, Apr 28, 2023 at 9:02 AM Romain Manni-Bucau
>  wrote:
> >
> > Le ven. 28 avr. 2023 à 08:36, Rémy Maucherat  a écrit :
> >
> > > On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
> > >  wrote:
> > > >
> > > > Hi
> > > >
> > > > Guess this utility should be there very early so before other
> > > starts/stops
> > > > sounds good but ultimately init/destroy is better since it avoids to
> > > create
> > > > custom utility threads in subcomponents init/destroy (more destroy
> for
> > > real
> > > > cases I think, not sure for init).
> > >
> > > The Server starts first and stops last, so it seems it will be fine. I
> > > don't quite see why it is a good idea to do utility tasks in init or
> > > destroyed (they should happen in start or stop).
> > > Right now the only item which needs to change is that the connector
> > > endpoint gets it on init. The other components were using it on start.
> > >
> >
> > Still in the spirit of being "stable" in terms of threads and avoiding to
> > create instances per components (which makes the machine under stress, in
> > particular when combined with colocalised deployments - k8s style or just
> > multiple processes locally.
> > The destroy usage I saw was mainly to push (broadcast) metrics captured
> > between stop and destroy by valves - but can ack it is a bit particular
> so
> > can not need something specific.
>
> We are talking about a Server.stop/start here, this is a very
> expensive process (TLS configs, and so on), and I don't understand why
> it would be a good idea to allow background tasks of subcomponents to
> keep running.
>

Server means more or less all the subgraph, it is not about leaking tasks
but dont break the backward compat since today it is allowed.


>
> > That said I'm not sure it fixes the spring-boot issue at all.
>
> Remy
>
> >
> > >
> > > Remy
> > >
> > > > What about getting it injected from the context and ignoring its
> > > lifecycle
> > > > ("external" notion)? Will keep it globally usable and integrate
> smoothly
> > > > with any env.
> > > >
> > > >
> > > > Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
> > > >
> > > > >
> > > > >
> > > > > > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> > > > > >
> > > > > > Hi all,
> > > > > >
> > > > > > As part of a discussion around a Spring Boot issue [1], the
> question
> > > has
> > > > > been raised whether there is merit in moving the Utility executor
> > > > > start/stop from StandardServer init/destroy to start/stop.
> > > > > >
> > > > > > I've looked at the code and I don't see any uses of the Executor
> > > until
> > > > > sub-components are in the start phase (there is a little copying of
> > > > > references that might need to move) so I think the change is
> doable.
> > > > >
> > > > > Maybe ContainerBase#startStopExecutor also need same operation
> above?
> > > > >
> > > > > >
> > > > > > The main advantage is that in the embedded scenario where there
> > > might be
> > > > > a long series of start / stop / start / stop etc, shutting down the
> > > > > executor on stop should avoid issues where executor tasks are not
> > > shutdown
> > > > > correctly. My brief code review suggested that Tomcat does this
> > > correctly
> > > > > but the executor is also exposed to application code.
> > > > > >
> > > > > > Thoughts?
> > > > > + 1
> > > > >
> > > > > >
> > > > > > Mark
> > > > > >
> > > > > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> > > > > >
> > > > > >
> -
> > > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > > > >
> > > > >
> > > > >
> > > > >
> -
> > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > > >
> > > > >
> > >
> > > -
> > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > >
> > >
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Utility Executor

2023-04-28 Thread Rémy Maucherat
On Fri, Apr 28, 2023 at 9:02 AM Romain Manni-Bucau
 wrote:
>
> Le ven. 28 avr. 2023 à 08:36, Rémy Maucherat  a écrit :
>
> > On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
> >  wrote:
> > >
> > > Hi
> > >
> > > Guess this utility should be there very early so before other
> > starts/stops
> > > sounds good but ultimately init/destroy is better since it avoids to
> > create
> > > custom utility threads in subcomponents init/destroy (more destroy for
> > real
> > > cases I think, not sure for init).
> >
> > The Server starts first and stops last, so it seems it will be fine. I
> > don't quite see why it is a good idea to do utility tasks in init or
> > destroyed (they should happen in start or stop).
> > Right now the only item which needs to change is that the connector
> > endpoint gets it on init. The other components were using it on start.
> >
>
> Still in the spirit of being "stable" in terms of threads and avoiding to
> create instances per components (which makes the machine under stress, in
> particular when combined with colocalised deployments - k8s style or just
> multiple processes locally.
> The destroy usage I saw was mainly to push (broadcast) metrics captured
> between stop and destroy by valves - but can ack it is a bit particular so
> can not need something specific.

We are talking about a Server.stop/start here, this is a very
expensive process (TLS configs, and so on), and I don't understand why
it would be a good idea to allow background tasks of subcomponents to
keep running.

> That said I'm not sure it fixes the spring-boot issue at all.

Remy

>
> >
> > Remy
> >
> > > What about getting it injected from the context and ignoring its
> > lifecycle
> > > ("external" notion)? Will keep it globally usable and integrate smoothly
> > > with any env.
> > >
> > >
> > > Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
> > >
> > > >
> > > >
> > > > > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> > > > >
> > > > > Hi all,
> > > > >
> > > > > As part of a discussion around a Spring Boot issue [1], the question
> > has
> > > > been raised whether there is merit in moving the Utility executor
> > > > start/stop from StandardServer init/destroy to start/stop.
> > > > >
> > > > > I've looked at the code and I don't see any uses of the Executor
> > until
> > > > sub-components are in the start phase (there is a little copying of
> > > > references that might need to move) so I think the change is doable.
> > > >
> > > > Maybe ContainerBase#startStopExecutor also need same operation above?
> > > >
> > > > >
> > > > > The main advantage is that in the embedded scenario where there
> > might be
> > > > a long series of start / stop / start / stop etc, shutting down the
> > > > executor on stop should avoid issues where executor tasks are not
> > shutdown
> > > > correctly. My brief code review suggested that Tomcat does this
> > correctly
> > > > but the executor is also exposed to application code.
> > > > >
> > > > > Thoughts?
> > > > + 1
> > > >
> > > > >
> > > > > Mark
> > > > >
> > > > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> > > > >
> > > > > -
> > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > > >
> > > >
> > > >
> > > > -
> > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > >
> > > >
> >
> > -
> > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > For additional commands, e-mail: dev-h...@tomcat.apache.org
> >
> >

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread Romain Manni-Bucau
Le ven. 28 avr. 2023 à 08:36, Rémy Maucherat  a écrit :

> On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
>  wrote:
> >
> > Hi
> >
> > Guess this utility should be there very early so before other
> starts/stops
> > sounds good but ultimately init/destroy is better since it avoids to
> create
> > custom utility threads in subcomponents init/destroy (more destroy for
> real
> > cases I think, not sure for init).
>
> The Server starts first and stops last, so it seems it will be fine. I
> don't quite see why it is a good idea to do utility tasks in init or
> destroyed (they should happen in start or stop).
> Right now the only item which needs to change is that the connector
> endpoint gets it on init. The other components were using it on start.
>

Still in the spirit of being "stable" in terms of threads and avoiding to
create instances per components (which makes the machine under stress, in
particular when combined with colocalised deployments - k8s style or just
multiple processes locally.
The destroy usage I saw was mainly to push (broadcast) metrics captured
between stop and destroy by valves - but can ack it is a bit particular so
can not need something specific.

That said I'm not sure it fixes the spring-boot issue at all.


>
> Remy
>
> > What about getting it injected from the context and ignoring its
> lifecycle
> > ("external" notion)? Will keep it globally usable and integrate smoothly
> > with any env.
> >
> >
> > Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
> >
> > >
> > >
> > > > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> > > >
> > > > Hi all,
> > > >
> > > > As part of a discussion around a Spring Boot issue [1], the question
> has
> > > been raised whether there is merit in moving the Utility executor
> > > start/stop from StandardServer init/destroy to start/stop.
> > > >
> > > > I've looked at the code and I don't see any uses of the Executor
> until
> > > sub-components are in the start phase (there is a little copying of
> > > references that might need to move) so I think the change is doable.
> > >
> > > Maybe ContainerBase#startStopExecutor also need same operation above?
> > >
> > > >
> > > > The main advantage is that in the embedded scenario where there
> might be
> > > a long series of start / stop / start / stop etc, shutting down the
> > > executor on stop should avoid issues where executor tasks are not
> shutdown
> > > correctly. My brief code review suggested that Tomcat does this
> correctly
> > > but the executor is also exposed to application code.
> > > >
> > > > Thoughts?
> > > + 1
> > >
> > > >
> > > > Mark
> > > >
> > > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> > > >
> > > > -
> > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > > >
> > >
> > >
> > > -
> > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > >
> > >
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Utility Executor

2023-04-28 Thread Han Li


> On Apr 28, 2023, at 14:35, Rémy Maucherat  wrote:
> 
> On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
> mailto:rmannibu...@gmail.com>> wrote:
>> 
>> Hi
>> 
>> Guess this utility should be there very early so before other starts/stops
>> sounds good but ultimately init/destroy is better since it avoids to create
>> custom utility threads in subcomponents init/destroy (more destroy for real
>> cases I think, not sure for init).
> 
> The Server starts first and stops last, so it seems it will be fine. I
> don't quite see why it is a good idea to do utility tasks in init or
> destroyed (they should happen in start or stop).
> Right now the only item which needs to change is that the connector
> endpoint gets it on init.
Not only connector, also include ContainerBase and SimpleTcpCluster which also 
too.
Although I am not familiar with the initialization of SimpleTcpCluster, the 
code exists in init method ;)

Han

> The other components were using it on start.
> 
> Remy
> 
>> What about getting it injected from the context and ignoring its lifecycle
>> ("external" notion)? Will keep it globally usable and integrate smoothly
>> with any env.
>> 
>> 
>> Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
>> 
>>> 
>>> 
>>>> On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
>>>> 
>>>> Hi all,
>>>> 
>>>> As part of a discussion around a Spring Boot issue [1], the question has
>>> been raised whether there is merit in moving the Utility executor
>>> start/stop from StandardServer init/destroy to start/stop.
>>>> 
>>>> I've looked at the code and I don't see any uses of the Executor until
>>> sub-components are in the start phase (there is a little copying of
>>> references that might need to move) so I think the change is doable.
>>> 
>>> Maybe ContainerBase#startStopExecutor also need same operation above?
>>> 
>>>> 
>>>> The main advantage is that in the embedded scenario where there might be
>>> a long series of start / stop / start / stop etc, shutting down the
>>> executor on stop should avoid issues where executor tasks are not shutdown
>>> correctly. My brief code review suggested that Tomcat does this correctly
>>> but the executor is also exposed to application code.
>>>> 
>>>> Thoughts?
>>> + 1
>>> 
>>>> 
>>>> Mark
>>>> 
>>>> [1] https://github.com/spring-projects/spring-boot/issues/34955
>>>> 
>>>> -
>>>> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
>>>> For additional commands, e-mail: dev-h...@tomcat.apache.org
>>>> 
>>> 
>>> 
>>> -
>>> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
>>> For additional commands, e-mail: dev-h...@tomcat.apache.org
>>> 
>>> 
> 
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org 
> <mailto:dev-unsubscr...@tomcat.apache.org>
> For additional commands, e-mail: dev-h...@tomcat.apache.org 
> <mailto:dev-h...@tomcat.apache.org>


Re: Utility Executor

2023-04-28 Thread Rémy Maucherat
On Fri, Apr 28, 2023 at 8:10 AM Romain Manni-Bucau
 wrote:
>
> Hi
>
> Guess this utility should be there very early so before other starts/stops
> sounds good but ultimately init/destroy is better since it avoids to create
> custom utility threads in subcomponents init/destroy (more destroy for real
> cases I think, not sure for init).

The Server starts first and stops last, so it seems it will be fine. I
don't quite see why it is a good idea to do utility tasks in init or
destroyed (they should happen in start or stop).
Right now the only item which needs to change is that the connector
endpoint gets it on init. The other components were using it on start.

Remy

> What about getting it injected from the context and ignoring its lifecycle
> ("external" notion)? Will keep it globally usable and integrate smoothly
> with any env.
>
>
> Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :
>
> >
> >
> > > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> > >
> > > Hi all,
> > >
> > > As part of a discussion around a Spring Boot issue [1], the question has
> > been raised whether there is merit in moving the Utility executor
> > start/stop from StandardServer init/destroy to start/stop.
> > >
> > > I've looked at the code and I don't see any uses of the Executor until
> > sub-components are in the start phase (there is a little copying of
> > references that might need to move) so I think the change is doable.
> >
> > Maybe ContainerBase#startStopExecutor also need same operation above?
> >
> > >
> > > The main advantage is that in the embedded scenario where there might be
> > a long series of start / stop / start / stop etc, shutting down the
> > executor on stop should avoid issues where executor tasks are not shutdown
> > correctly. My brief code review suggested that Tomcat does this correctly
> > but the executor is also exposed to application code.
> > >
> > > Thoughts?
> > + 1
> >
> > >
> > > Mark
> > >
> > > [1] https://github.com/spring-projects/spring-boot/issues/34955
> > >
> > > -
> > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > > For additional commands, e-mail: dev-h...@tomcat.apache.org
> > >
> >
> >
> > -
> > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > For additional commands, e-mail: dev-h...@tomcat.apache.org
> >
> >

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-28 Thread Romain Manni-Bucau
Hi

Guess this utility should be there very early so before other starts/stops
sounds good but ultimately init/destroy is better since it avoids to create
custom utility threads in subcomponents init/destroy (more destroy for real
cases I think, not sure for init).

What about getting it injected from the context and ignoring its lifecycle
("external" notion)? Will keep it globally usable and integrate smoothly
with any env.


Le ven. 28 avr. 2023 à 04:27, Han Li  a écrit :

>
>
> > On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> >
> > Hi all,
> >
> > As part of a discussion around a Spring Boot issue [1], the question has
> been raised whether there is merit in moving the Utility executor
> start/stop from StandardServer init/destroy to start/stop.
> >
> > I've looked at the code and I don't see any uses of the Executor until
> sub-components are in the start phase (there is a little copying of
> references that might need to move) so I think the change is doable.
>
> Maybe ContainerBase#startStopExecutor also need same operation above?
>
> >
> > The main advantage is that in the embedded scenario where there might be
> a long series of start / stop / start / stop etc, shutting down the
> executor on stop should avoid issues where executor tasks are not shutdown
> correctly. My brief code review suggested that Tomcat does this correctly
> but the executor is also exposed to application code.
> >
> > Thoughts?
> + 1
>
> >
> > Mark
> >
> > [1] https://github.com/spring-projects/spring-boot/issues/34955
> >
> > -
> > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> > For additional commands, e-mail: dev-h...@tomcat.apache.org
> >
>
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Utility Executor

2023-04-27 Thread Han Li



> On Apr 28, 2023, at 00:33, Mark Thomas  wrote:
> 
> Hi all,
> 
> As part of a discussion around a Spring Boot issue [1], the question has been 
> raised whether there is merit in moving the Utility executor start/stop from 
> StandardServer init/destroy to start/stop.
> 
> I've looked at the code and I don't see any uses of the Executor until 
> sub-components are in the start phase (there is a little copying of 
> references that might need to move) so I think the change is doable.

Maybe ContainerBase#startStopExecutor also need same operation above?

> 
> The main advantage is that in the embedded scenario where there might be a 
> long series of start / stop / start / stop etc, shutting down the executor on 
> stop should avoid issues where executor tasks are not shutdown correctly. My 
> brief code review suggested that Tomcat does this correctly but the executor 
> is also exposed to application code.
> 
> Thoughts?
+ 1

> 
> Mark
> 
> [1] https://github.com/spring-projects/spring-boot/issues/34955
> 
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
> 


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Utility Executor

2023-04-27 Thread Rémy Maucherat
On Thu, Apr 27, 2023 at 6:34 PM Mark Thomas  wrote:
>
> Hi all,
>
> As part of a discussion around a Spring Boot issue [1], the question has
> been raised whether there is merit in moving the Utility executor
> start/stop from StandardServer init/destroy to start/stop.
>
> I've looked at the code and I don't see any uses of the Executor until
> sub-components are in the start phase (there is a little copying of
> references that might need to move) so I think the change is doable.
>
> The main advantage is that in the embedded scenario where there might be
> a long series of start / stop / start / stop etc, shutting down the
> executor on stop should avoid issues where executor tasks are not
> shutdown correctly. My brief code review suggested that Tomcat does this
> correctly but the executor is also exposed to application code.
>
> Thoughts?

I think I put it here in case there would be utility tasks to do on
init, but that's probably not a good design. So you can try to move
it, and see if something breaks ;)

Rémy

>
> Mark
>
> [1] https://github.com/spring-projects/spring-boot/issues/34955
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Utility Executor

2023-04-27 Thread Mark Thomas

Hi all,

As part of a discussion around a Spring Boot issue [1], the question has 
been raised whether there is merit in moving the Utility executor 
start/stop from StandardServer init/destroy to start/stop.


I've looked at the code and I don't see any uses of the Executor until 
sub-components are in the start phase (there is a little copying of 
references that might need to move) so I think the change is doable.


The main advantage is that in the embedded scenario where there might be 
a long series of start / stop / start / stop etc, shutting down the 
executor on stop should avoid issues where executor tasks are not 
shutdown correctly. My brief code review suggested that Tomcat does this 
correctly but the executor is also exposed to application code.


Thoughts?

Mark

[1] https://github.com/spring-projects/spring-boot/issues/34955

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] branch 9.0.x updated: Expose utility executor to webapps

2023-04-11 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
 new 4e3972d33d Expose utility executor to webapps
4e3972d33d is described below

commit 4e3972d33d38c14e8de26240f4d13675273c4e81
Author: remm 
AuthorDate: Tue Apr 11 10:10:04 2023 +0200

Expose utility executor to webapps

Part of the discussions in PR#607
Only enabled when the security manager is not active.
---
 java/org/apache/catalina/core/StandardContext.java | 7 +++
 webapps/docs/changelog.xml | 5 +
 2 files changed, 12 insertions(+)

diff --git a/java/org/apache/catalina/core/StandardContext.java 
b/java/org/apache/catalina/core/StandardContext.java
index 6a7a03bcb0..5dbeae925c 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -135,6 +135,7 @@ import org.apache.tomcat.util.http.Rfc6265CookieProcessor;
 import org.apache.tomcat.util.scan.StandardJarScanner;
 import org.apache.tomcat.util.security.PrivilegedGetTccl;
 import org.apache.tomcat.util.security.PrivilegedSetTccl;
+import org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor;
 
 /**
  * Standard implementation of the Context interface. Each child 
container must be a Wrapper implementation to
@@ -4918,6 +4919,12 @@ public class StandardContext extends ContainerBase 
implements Context, Notificat
 
 // Make the version info available
 getServletContext().setAttribute(Globals.WEBAPP_VERSION, 
getWebappVersion());
+
+// Make the utility executor available
+if (!Globals.IS_SECURITY_ENABLED) {
+
getServletContext().setAttribute(ScheduledThreadPoolExecutor.class.getName(),
+
Container.getService(this).getServer().getUtilityExecutor());
+}
 }
 
 // Set up the context init params
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 60626d2702..7d4dd421f0 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -175,6 +175,11 @@
 avoid possible JVM thread creation in the webapp context on some
 platforms. (remm)
   
+  
+Make the server utility executor available to webapps using a Servlet
+context attribute named
+
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor. (remm)
+  
 
   
   


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] branch 10.1.x updated: Expose utility executor to webapps

2023-04-11 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
 new fe797d1417 Expose utility executor to webapps
fe797d1417 is described below

commit fe797d141723bd088825707b85b6c8abc957d012
Author: remm 
AuthorDate: Tue Apr 11 10:10:04 2023 +0200

Expose utility executor to webapps

Part of the discussions in PR#607
Only enabled when the security manager is not active.
---
 java/org/apache/catalina/core/StandardContext.java | 7 +++
 webapps/docs/changelog.xml | 5 +
 2 files changed, 12 insertions(+)

diff --git a/java/org/apache/catalina/core/StandardContext.java 
b/java/org/apache/catalina/core/StandardContext.java
index 4e6af40ba0..34bbc4ac2d 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -134,6 +134,7 @@ import org.apache.tomcat.util.http.Rfc6265CookieProcessor;
 import org.apache.tomcat.util.scan.StandardJarScanner;
 import org.apache.tomcat.util.security.PrivilegedGetTccl;
 import org.apache.tomcat.util.security.PrivilegedSetTccl;
+import org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor;
 
 /**
  * Standard implementation of the Context interface. Each child 
container must be a Wrapper implementation to
@@ -4864,6 +4865,12 @@ public class StandardContext extends ContainerBase 
implements Context, Notificat
 
 // Make the version info available
 getServletContext().setAttribute(Globals.WEBAPP_VERSION, 
getWebappVersion());
+
+// Make the utility executor available
+if (!Globals.IS_SECURITY_ENABLED) {
+
getServletContext().setAttribute(ScheduledThreadPoolExecutor.class.getName(),
+
Container.getService(this).getServer().getUtilityExecutor());
+}
 }
 
 // Set up the context init params
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index e084cbd1c3..b5792a67e3 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -175,6 +175,11 @@
 avoid possible JVM thread creation in the webapp context on some
 platforms. (remm)
   
+  
+Make the server utility executor available to webapps using a Servlet
+context attribute named
+
org.apache.tomcat.util.threads.ScheduledThreadPoolExecutor. (remm)
+  
 
   
   


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: [tomcat] branch master updated: Use utility executor for scanning

2020-09-18 Thread Rémy Maucherat
On Fri, Sep 18, 2020 at 12:06 PM Mark Thomas  wrote:

> On 18/09/2020 10:40, r...@apache.org wrote:
> > This is an automated email from the ASF dual-hosted git repository.
> >
> > remm pushed a commit to branch master
> > in repository https://gitbox.apache.org/repos/asf/tomcat.git
> >
> >
> > The following commit(s) were added to refs/heads/master by this push:
> >  new 27bb36b  Use utility executor for scanning
> > 27bb36b is described below
> >
> > commit 27bb36bdaa56d62fdcc28d3b8e3d4c25f4a44a50
> > Author: remm 
> > AuthorDate: Fri Sep 18 11:40:17 2020 +0200
> >
> > Use utility executor for scanning
> >
> > PR354 submitted by Jatin Kamnani.
> > The flag in on the context, as that's where it belongs. Defaults to
> > false, can be configured through the context defaults or per context.
>
> 
>
> > +protected void processAnnotationsInParallel(Set fragments,
> boolean handlesTypesOnly,
> > +Map JavaClassCacheEntry> javaClassCache) {
> > +Server s = getServer();
> > +ExecutorService pool = null;
> > +try {
> > +pool = s.getUtilityExecutor();
> > +List> futures = new ArrayList<>(fragments.size());
> > +for (WebXml fragment : fragments) {
> > +Runnable task = new AnnotationScanTask(fragment,
> handlesTypesOnly, javaClassCache);
> > +futures.add(pool.submit(task));
> > +}
> > +try {
> > +for (Future future : futures) {
> > +future.get();
> > +}
> > +} catch (Exception e) {
> > +throw new
> RuntimeException(sm.getString("contextConfig.processAnnotationsInParallelFailure"),
> e);
> > +}
> > +} finally {
> > +if (pool != null) {
> > +pool.shutdownNow();
> > +}
> >  }
> >  }
>
> Why is the executor being shutdown here? What about other Tomcat
> components that might be using it or want to use it in the future?
>

I forgot to remove that. It does nothing since there's a facade for the
executor which does a noop there.

Rémy


Re: [tomcat] branch master updated: Use utility executor for scanning

2020-09-18 Thread Mark Thomas
On 18/09/2020 10:40, r...@apache.org wrote:
> This is an automated email from the ASF dual-hosted git repository.
> 
> remm pushed a commit to branch master
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
> 
> 
> The following commit(s) were added to refs/heads/master by this push:
>  new 27bb36b  Use utility executor for scanning
> 27bb36b is described below
> 
> commit 27bb36bdaa56d62fdcc28d3b8e3d4c25f4a44a50
> Author: remm 
> AuthorDate: Fri Sep 18 11:40:17 2020 +0200
> 
> Use utility executor for scanning
> 
> PR354 submitted by Jatin Kamnani.
> The flag in on the context, as that's where it belongs. Defaults to
> false, can be configured through the context defaults or per context.



> +protected void processAnnotationsInParallel(Set fragments, 
> boolean handlesTypesOnly,
> +Map JavaClassCacheEntry> javaClassCache) {
> +Server s = getServer();
> +ExecutorService pool = null;
> +try {
> +pool = s.getUtilityExecutor();
> +List> futures = new ArrayList<>(fragments.size());
> +for (WebXml fragment : fragments) {
> +Runnable task = new AnnotationScanTask(fragment, 
> handlesTypesOnly, javaClassCache);
> +futures.add(pool.submit(task));
> +}
> +try {
> +for (Future future : futures) {
> +future.get();
> +}
> +} catch (Exception e) {
> +throw new 
> RuntimeException(sm.getString("contextConfig.processAnnotationsInParallelFailure"),
>  e);
> +}
> +} finally {
> +if (pool != null) {
> +pool.shutdownNow();
> +}
>  }
>  }

Why is the executor being shutdown here? What about other Tomcat
components that might be using it or want to use it in the future?

Mark

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] branch 9.0.x updated: Use utility executor for scanning

2020-09-18 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
 new 101476c  Use utility executor for scanning
101476c is described below

commit 101476c3536ac09a105d0b603b2c51dd0f3770e9
Author: remm 
AuthorDate: Fri Sep 18 11:40:17 2020 +0200

Use utility executor for scanning

PR354 submitted by Jatin Kamnani.
The flag in on the context, as that's where it belongs. Defaults to
false, can be configured through the context defaults or per context.
---
 java/org/apache/catalina/Context.java  |  14 +++
 java/org/apache/catalina/core/StandardContext.java |  19 
 .../apache/catalina/core/mbeans-descriptors.xml|   4 +
 .../org/apache/catalina/startup/ContextConfig.java | 116 +
 .../org/apache/catalina/startup/FailedContext.java |   6 ++
 .../catalina/startup/LocalStrings.properties   |   1 +
 test/org/apache/tomcat/unittest/TesterContext.java |   6 ++
 webapps/docs/changelog.xml |   4 +
 webapps/docs/config/context.xml|   8 ++
 9 files changed, 156 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/Context.java 
b/java/org/apache/catalina/Context.java
index 3e647dc..5aac225 100644
--- a/java/org/apache/catalina/Context.java
+++ b/java/org/apache/catalina/Context.java
@@ -761,6 +761,20 @@ public interface Context extends Container, ContextBind {
 public String getContainerSciFilter();
 
 
+/**
+ * @return the value of the parallel annotation scanning flag.  If true,
+ * it will dispatch scanning to the utility executor.
+ */
+public boolean isParallelAnnotationScanning();
+
+/**
+ * Set the parallel annotation scanning value.
+ *
+ * @param parallelAnnotationScanning new parallel annotation scanning flag
+ */
+public void setParallelAnnotationScanning(boolean 
parallelAnnotationScanning);
+
+
 // - Public Methods
 
 /**
diff --git a/java/org/apache/catalina/core/StandardContext.java 
b/java/org/apache/catalina/core/StandardContext.java
index 12641d7..06f7621 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -828,6 +828,8 @@ public class StandardContext extends ContainerBase
 private boolean createUploadTargets = false;
 
 
+private boolean parallelAnnotationScanning = false;
+
 // - Context Properties
 
 @Override
@@ -1404,6 +1406,23 @@ public class StandardContext extends ContainerBase
 }
 
 
+@Override
+public void setParallelAnnotationScanning(boolean 
parallelAnnotationScanning) {
+
+boolean oldParallelAnnotationScanning = 
this.parallelAnnotationScanning;
+this.parallelAnnotationScanning = parallelAnnotationScanning;
+support.firePropertyChange("parallelAnnotationScanning", 
oldParallelAnnotationScanning,
+this.parallelAnnotationScanning);
+
+}
+
+
+@Override
+public boolean isParallelAnnotationScanning() {
+return this.parallelAnnotationScanning;
+}
+
+
 /**
  * @return the Locale to character set mapper for this Context.
  */
diff --git a/java/org/apache/catalina/core/mbeans-descriptors.xml 
b/java/org/apache/catalina/core/mbeans-descriptors.xml
index 1c0733f..50be99f 100644
--- a/java/org/apache/catalina/core/mbeans-descriptors.xml
+++ b/java/org/apache/catalina/core/mbeans-descriptors.xml
@@ -208,6 +208,10 @@
description="The name of this Context"
type="java.lang.String"/>
 
+
+
 
diff --git a/java/org/apache/catalina/startup/ContextConfig.java 
b/java/org/apache/catalina/startup/ContextConfig.java
index d7b5a77..3dc1638 100644
--- a/java/org/apache/catalina/startup/ContextConfig.java
+++ b/java/org/apache/catalina/startup/ContextConfig.java
@@ -39,6 +39,8 @@ import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 import javax.servlet.MultipartConfigElement;
 import javax.servlet.ServletContainerInitializer;
@@ -122,7 +124,6 @@ public class ContextConfig implements LifecycleListener {
 
 private static final Log log = LogFactory.getLog(ContextConfig.class);
 
-
 /**
  * The string resources for this package.
  */
@@ -1374,7 +1375,14 @@ public class ContextConfig implements LifecycleListener {
 protected void processClasses(WebXml webXml, Set orderedFragments) 
{
 // Step 4. Process /WEB-INF/classes for annotations and
 // @HandlesTypes matches
-Map javaClassCache = new HashMap&l

[tomcat] branch master updated: Use utility executor for scanning

2020-09-18 Thread remm
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
 new 27bb36b  Use utility executor for scanning
27bb36b is described below

commit 27bb36bdaa56d62fdcc28d3b8e3d4c25f4a44a50
Author: remm 
AuthorDate: Fri Sep 18 11:40:17 2020 +0200

Use utility executor for scanning

PR354 submitted by Jatin Kamnani.
The flag in on the context, as that's where it belongs. Defaults to
false, can be configured through the context defaults or per context.
---
 java/org/apache/catalina/Context.java  |  14 +++
 java/org/apache/catalina/core/StandardContext.java |  19 
 .../apache/catalina/core/mbeans-descriptors.xml|   4 +
 .../org/apache/catalina/startup/ContextConfig.java | 116 +
 .../org/apache/catalina/startup/FailedContext.java |   5 +
 .../catalina/startup/LocalStrings.properties   |   1 +
 test/org/apache/tomcat/unittest/TesterContext.java |   5 +
 webapps/docs/changelog.xml |   4 +
 webapps/docs/config/context.xml|   8 ++
 9 files changed, 154 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/Context.java 
b/java/org/apache/catalina/Context.java
index b8f55a0..4cf844c 100644
--- a/java/org/apache/catalina/Context.java
+++ b/java/org/apache/catalina/Context.java
@@ -762,6 +762,20 @@ public interface Context extends Container, ContextBind {
 public String getContainerSciFilter();
 
 
+/**
+ * @return the value of the parallel annotation scanning flag.  If true,
+ * it will dispatch scanning to the utility executor.
+ */
+public boolean isParallelAnnotationScanning();
+
+/**
+ * Set the parallel annotation scanning value.
+ *
+ * @param parallelAnnotationScanning new parallel annotation scanning flag
+ */
+public void setParallelAnnotationScanning(boolean 
parallelAnnotationScanning);
+
+
 // - Public Methods
 
 /**
diff --git a/java/org/apache/catalina/core/StandardContext.java 
b/java/org/apache/catalina/core/StandardContext.java
index ce51d6c..a34f14e 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -833,6 +833,8 @@ public class StandardContext extends ContainerBase
 
 private boolean dispatcherWrapsSameObject = 
Globals.STRICT_SERVLET_COMPLIANCE;
 
+private boolean parallelAnnotationScanning = false;
+
 // - Context Properties
 
 @Override
@@ -1447,6 +1449,23 @@ public class StandardContext extends ContainerBase
 }
 
 
+@Override
+public void setParallelAnnotationScanning(boolean 
parallelAnnotationScanning) {
+
+boolean oldParallelAnnotationScanning = 
this.parallelAnnotationScanning;
+this.parallelAnnotationScanning = parallelAnnotationScanning;
+support.firePropertyChange("parallelAnnotationScanning", 
oldParallelAnnotationScanning,
+this.parallelAnnotationScanning);
+
+}
+
+
+@Override
+public boolean isParallelAnnotationScanning() {
+return this.parallelAnnotationScanning;
+}
+
+
 /**
  * @return the Locale to character set mapper for this Context.
  */
diff --git a/java/org/apache/catalina/core/mbeans-descriptors.xml 
b/java/org/apache/catalina/core/mbeans-descriptors.xml
index 1c0733f..50be99f 100644
--- a/java/org/apache/catalina/core/mbeans-descriptors.xml
+++ b/java/org/apache/catalina/core/mbeans-descriptors.xml
@@ -208,6 +208,10 @@
description="The name of this Context"
type="java.lang.String"/>
 
+
+
 
diff --git a/java/org/apache/catalina/startup/ContextConfig.java 
b/java/org/apache/catalina/startup/ContextConfig.java
index c1fe029..a3cfcb8 100644
--- a/java/org/apache/catalina/startup/ContextConfig.java
+++ b/java/org/apache/catalina/startup/ContextConfig.java
@@ -39,6 +39,8 @@ import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 import jakarta.servlet.MultipartConfigElement;
 import jakarta.servlet.ServletContainerInitializer;
@@ -122,7 +124,6 @@ public class ContextConfig implements LifecycleListener {
 
 private static final Log log = LogFactory.getLog(ContextConfig.class);
 
-
 /**
  * The string resources for this package.
  */
@@ -1374,7 +1375,14 @@ public class ContextConfig implements LifecycleListener {
 protected void processClasses(WebXml webXml, Set orderedFragments) 
{
 // Step 4. Process /WEB-INF/classes for annotations and
 // @HandlesTypes matches
-