[jira] [Updated] (UIMA-6412) Stop using ThreadGroup in CPMEngine
[ https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Richard Eckart de Castilho updated UIMA-6412: - Description: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * ... > Stop using ThreadGroup in CPMEngine > --- > > Key: UIMA-6412 > URL: https://issues.apache.org/jira/browse/UIMA-6412 > Project: UIMA > Issue Type: Improvement > Components: Collection Processing >Reporter: Richard Eckart de Castilho >Assignee: Richard Eckart de Castilho >Priority: Major > Fix For: 3.3.0SDK > > > The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker > threads. This causes a problem with concurrency features present in modern > Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} > which is used by concurrency features by default when no other pool is > specified. But even if a custom pool is used, the problem persists. The > problem is that threads launched from within the context of a thread that is > part of a thread group inherits that thread group as its parent. > Consequently, worker threads launched e.g. by the > {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common > pool worker threads are long-lived and re-used. the CPM thread group however > refuses to shut down as long as there are still threads in it. That > essentially blocks the use of many concurrency features within the scope of a > CPE. > The best approach would probably be to replace the {{CPMThreadGroup}} with > some kind of {{CPMExecutorService}} which essentially performs the same > duties as the thread group but without being a thread group. > * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught > exceptions at the level of the thread group, an exception handler needs to be > installed in the individual spawned threads > * ... -- This message was sent by Atlassian Jira (v8.20.1#820001)
[jira] [Updated] (UIMA-6412) Stop using ThreadGroup in CPMEngine
[ https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Richard Eckart de Castilho updated UIMA-6412: - Description: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. was: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * ... > Stop using ThreadGroup in CPMEngine > --- > > Key: UIMA-6412 > URL: https://issues.apache.org/jira/browse/UIMA-6412 > Project: UIMA > Issue Type: Improvement > Components: Collection Processing >Reporter: Richard Eckart de Castilho >Assignee: Richard Eckart de Castilho >Priority: Major > Fix For: 3.3.0SDK > > > The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker > threads. This causes a problem with concurrency features present in modern > Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} > which is used by concurrency features by default when no other pool is > specified. But even if a custom pool is used, the problem persists. The > problem is that threads launched from within the context of a thread that is > part of a thread group inherits that thread group as its parent. > Consequently, worker threads launched e.g. by the > {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common > pool worker threads are long-lived and re-used. the CPM thread group however > refuses to shut down as long as there are still threads in it. That > essentially blocks the use of many concurrency features within the scope of a > CPE. > The best approach would probably be to replace the {{CPMThreadGroup}} with > some kind of {{CPMExecutorService}} which essentially performs the same > duties as the thread group but without being a thread group. > * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught > exceptions at the level of the thread group, an exception handler needs to be > inst
[jira] [Updated] (UIMA-6412) Stop using ThreadGroup in CPMEngine
[ https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Richard Eckart de Castilho updated UIMA-6412: - Description: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. * worker threads must not be started by callling {{start()}} explicitly but rather by submitting them to the executor service was: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. > Stop using ThreadGroup in CPMEngine > --- > > Key: UIMA-6412 > URL: https://issues.apache.org/jira/browse/UIMA-6412 > Project: UIMA > Issue Type: Improvement > Components: Collection Processing >Reporter: Richard Eckart de Castilho >Assignee: Richard Eckart de Castilho >Priority: Major > Fix For: 3.3.0SDK > > > The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker > threads. This causes a problem with concurrency features present in modern > Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} > which is used by concurrency features by default when no other pool is > specified. But even if a custom pool is used, the problem persists. The > problem is that threads launched from within the context of a thread that is > part of a thread group inherits that thread group as its parent. > Consequently, worker threads launched e.g. by the > {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common > pool worker threads are long-lived and re-used. the CPM thr
[jira] [Updated] (UIMA-6412) Stop using ThreadGroup in CPMEngine
[ https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Richard Eckart de Castilho updated UIMA-6412: - Description: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. * worker threads must not be started by callling {{start()}} explicitly but rather by submitting them to the executor service * The CPE allows configuring a custom output queue (instance of {{BoundedWorkQueue}}. There is one subclass of {{BoundedWorkQueue}} provided by UIMA which is the {{SequencedQueue}} and it internally spawns a new {{ExpirationTimer}} thread. In the current implementation, this timer thread would block the thread group from shutting down. However, the task of the {{ExpirationTimer}} is just to remove a map entry after a certain amount of time - it is not a long running thread. So I think that it doesn't matter that it won't block the execution service from shutting down and also that we do not have to change the API for registering custom output queues to pass the execution service into the custom queues. There might be custom queues which rely on the thread group being blocked, but I somewhat doubt it - and if so, those will then have to change their implementation... I'd still call this a feature release change and not a major release change. was: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. * worker threads must not be started by callling {{start()}} explicitly but rather by submitting them to the executor service > Stop using ThreadGroup in CPMEngine > --- > >
[jira] [Updated] (UIMA-6412) Stop using ThreadGroup in CPMEngine
[ https://issues.apache.org/jira/browse/UIMA-6412?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Richard Eckart de Castilho updated UIMA-6412: - Description: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMThreadGroup}}-instances piling up over time. I guess the replacement would be to call {{shutdown()}} on the replacement executor service. {{shutdown()}} causes the executor service not to accept any new tasks and once all running tasks are done, it cleans itself up. * worker threads must not be started by callling {{start()}} explicitly but rather by submitting them to the executor service * The CPE allows configuring a custom output queue (instance of {{BoundedWorkQueue}}. There is one subclass of {{BoundedWorkQueue}} provided by UIMA which is the {{SequencedQueue}} and it internally spawns a new {{ExpirationTimer}} thread. In the current implementation, this timer thread would block the thread group from shutting down. However, the task of the {{ExpirationTimer}} is just to remove a map entry after a certain amount of time - it is not a long running thread. So I think that it doesn't matter that it won't block the execution service from shutting down and also that we do not have to change the API for registering custom output queues to pass the execution service into the custom queues. There might be custom queues which rely on the thread group being blocked, but I somewhat doubt it - and if so, those will then have to change their implementation... I'd still call this a feature release change and not a major release change. * This removes the public {{CPMThreadGroup}} class and replaces it with a {{CPMExecutorService}}. Again this is a change of an API that is in principle public and such changes should only be done in major releases. But again, I doubt that anybody really depends on this particular API. I think it is mainly public because the class is used by another class in a different package and otherwise it should be considered internal. So - IMHO - fine for a feature-level release. was: The {{CPMEngine}} internally uses a {{ThreadGroup}} to manage the worker threads. This causes a problem with concurrency features present in modern Java versions, e.g. the static system-wide {{ForkJoinPool.commonPool()}} which is used by concurrency features by default when no other pool is specified. But even if a custom pool is used, the problem persists. The problem is that threads launched from within the context of a thread that is part of a thread group inherits that thread group as its parent. Consequently, worker threads launched e.g. by the {{ForkJoinPool.commonPool()}} become part of the CPM thread group. The common pool worker threads are long-lived and re-used. the CPM thread group however refuses to shut down as long as there are still threads in it. That essentially blocks the use of many concurrency features within the scope of a CPE. The best approach would probably be to replace the {{CPMThreadGroup}} with some kind of {{CPMExecutorService}} which essentially performs the same duties as the thread group but without being a thread group. * {{CPMThreadGroup.uncaughtException()}} - instead of handling the uncaught exceptions at the level of the thread group, an exception handler needs to be installed in the individual spawned threads * {{ThreadGroupDestroyer}} - this is the code that currently waits until all threads in the {{CPMThreadGroup}} are finished and then destroys the group to avoid {{CPMTh