Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: None
    • Fix Version/s: 2.4
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-377Revist thread pooling strategy
      KULRICE-7944Change view pooling to use a thread pool
      KULRICE-8268broker pool optimization (4067)
      KULRICE-6413Remove BusAdminService and ability to "update" pool settings from the "Thread Pool" user interface as it's functionality is currently problematic
      KULRICE-10930Create Automated Functional (Smoke) Tests for Service Bus (old sample app)
      KULRICE-9497Convert Administration > Service Bus screens to KRAD
      KULRICE-3256Fix setting of KSB Thread pool size - config property never used
      KULRICE-564Pool starting before the availability of services with messages in the queue
      KULRICE-12962Make Bitronix the default connection pooling & JTA provider
      KULRICE-5959Create CI integration test job configured to use Bitronix for JTA transaction management and for connection pooling
    • Epic Link:
    • Rice Module:
      KRAD
    • Sprint:
      2.4.0-m2 KRAD Sprint 3, 2.4.0-m2 KRAD Sprint 4, 2.4.0-m3 KRAD Sprint 1
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required
    • Code Review Status:
      Not Required
    • Include in Release Notes?:
      Yes

      Description

      Thread pool configuration and queueing algorithm:
      Assemble processing tasks into a concurrent execution queue and establish a thread pool and mechanism to manage submission and notification.

        Issue Links

          Activity

          Hide
          Mark Fyffe (Inactive) added a comment -

          Continuing work started on KULRICE-10547 to refactor view/component lifecycle into discrete processing tasks.

          Moved viewStatus property from View to ComponentBase, and added to Component interface.

          The initialize phase, and all related helper methods has moved from ViewLifecycle to InitializeComponentPhase. The initialized phase is now tail recursive, and is ready for multi-threaded queueing.

          Now working to refactor apply model and finalize phases.

          Show
          Mark Fyffe (Inactive) added a comment - Continuing work started on KULRICE-10547 to refactor view/component lifecycle into discrete processing tasks. Moved viewStatus property from View to ComponentBase, and added to Component interface. The initialize phase, and all related helper methods has moved from ViewLifecycle to InitializeComponentPhase. The initialized phase is now tail recursive, and is ready for multi-threaded queueing. Now working to refactor apply model and finalize phases.
          Hide
          Mark Fyffe (Inactive) added a comment -

          Completed lifecycle phase refactoring and queueing algorithm.

          1. Moved buildView() from ViewService to ViewLifecycle.
          2. Added isInitialized(), isModelApplied(), isFinal(), and isRendered() methods to Component.
          3. Moved performComponentApplyModel() and all related methods from ViewLifecycle to discrete lifecycle phase processing task ApplyModelComponentPhase.
          4. Moved performComponentFinalize() and all related methods from ViewLifecycle to discrete lifecycle phase processing task FinalizeComponentPhase.
          5. Changed spawnSubLifecycle to queue sub-lifecycle phases after applying component IDs, rather than process inline.
          6. Modified inline references to performComponentInitialize to call spawnSubLifecycle instead.

          Cleanup following implementation of the queueing algorithm took a little longer than expected. I had initially set IAE to be thrown when attempting to queue a lifecycle phase for a component that already has the targeted view status, and for ISE to be thrown when attempting to process a component without the required view status. This helped uncover some lifecycle processing issues, but prior to commit I downgraded these to warning conditions for further review without impacting stability. Cleanup uncovered by these conditions:

          1. Duplicate entry of breadcrumb items in View.getComponentsForLifecycle()
          2. Inclusion of fieldLabel as nested under FieldBase when isLabelRendered() is true. In this case, the label becomes a child of the owning group when LabelSeparateModifier runs.
          3. Several areas where performApplyModel was called twice: once from spawnSubLifecycle, then again as a nested component.

          The only page I found where invalid status warnings still appear is Kitchen Sink "Other Examples". Remaining KRAD pages in sampleapp and krad-sampleapp appear to work well without lifecycle phase violations in single-threaded mode.

          Will configure a thread pool and convert queueing to multi-threaded operation once KULRICE-10548 is complete.

          Show
          Mark Fyffe (Inactive) added a comment - Completed lifecycle phase refactoring and queueing algorithm. Moved buildView() from ViewService to ViewLifecycle. Added isInitialized(), isModelApplied(), isFinal(), and isRendered() methods to Component. Moved performComponentApplyModel() and all related methods from ViewLifecycle to discrete lifecycle phase processing task ApplyModelComponentPhase. Moved performComponentFinalize() and all related methods from ViewLifecycle to discrete lifecycle phase processing task FinalizeComponentPhase. Changed spawnSubLifecycle to queue sub-lifecycle phases after applying component IDs, rather than process inline. Modified inline references to performComponentInitialize to call spawnSubLifecycle instead. Cleanup following implementation of the queueing algorithm took a little longer than expected. I had initially set IAE to be thrown when attempting to queue a lifecycle phase for a component that already has the targeted view status, and for ISE to be thrown when attempting to process a component without the required view status. This helped uncover some lifecycle processing issues, but prior to commit I downgraded these to warning conditions for further review without impacting stability. Cleanup uncovered by these conditions: Duplicate entry of breadcrumb items in View.getComponentsForLifecycle() Inclusion of fieldLabel as nested under FieldBase when isLabelRendered() is true. In this case, the label becomes a child of the owning group when LabelSeparateModifier runs. Several areas where performApplyModel was called twice: once from spawnSubLifecycle, then again as a nested component. The only page I found where invalid status warnings still appear is Kitchen Sink "Other Examples". Remaining KRAD pages in sampleapp and krad-sampleapp appear to work well without lifecycle phase violations in single-threaded mode. Will configure a thread pool and convert queueing to multi-threaded operation once KULRICE-10548 is complete.
          Hide
          Mark Fyffe (Inactive) added a comment -

          Completed thread pool configuration and phase queueing algorithm. Several clean-up items following recent refactoring accompany this update.

          View lifecycle is now controlled by the following configuration parameters:

          • rice.krad.lifecycle.trace - enables the logging of processing data related to lifecycle phase processing. This property is particularly useful for troubleshooting asynchronous operation. Default is false.
          • rice.krad.lifecycle.asynchronous - enables asynchronous phase processing. When set to true, lifecycle phases will be performed using pooled worker threads. When false, the original single-threaded lifecycle process is used. Default is false.
          • rice.krad.lifecycle.asynchronous.minThreads - defines the minimum number of worker threads to maintain when asynchronous processing is enabled. This setting has no effect on single-threaded lifecycle processing. The default setting is 4.
          • rice.krad.lifecycle.asynchronous.minThreads - defines the maximum number of worker threads to allow in the pool when asynchronous processing is enabled. This setting has no effect on single-threaded lifecycle processing. The default setting is 48.
          • rice.krad.lifecycle.asynchronous.timeout - defines the time, in milliseconds, to wait for asynchronous lifecycle processing to complete before giving up. One the timeout has reached, any pending phases will be canceled.

          Changes related to this feature are:

          • Converted all MessageMap lists to be synchronized. In single-threaded mode, these lists should be effectively thread-local but in multi-threaded mode (including multiple requests), they are important to synchronize as recommended in the API documentation for AutoPopulatingList.
          • Moved importTemplate() calls from the finalize phase to the render phase, since rendering may take place in a different thread, which may have a different rendering context.
          • Restructured prepare() and LifecyclePhaseFactory() methods
          • Split processing details out from ViewLifecycle into the new ViewLifecycleProcessor interface.
            • The original single-threaded behavior is supported by SynchronousViewLifecycleProcessor.
            • The multi-threaded behavior is supported by AsynchronousViewLifecycleProcessor.
          • Converted lifecycle phase tree for bottom-up traversal only.
            • Child and sibling references have been removed in favor of pending counts. This consideration eliminates the need to synchronize on lists during phase complete notification.
            • Phases now have only a single predecessor, rather than a list of mulitple predecssors. Precessor phases are assigned dynamically.
          • Pushed rendering phase creation down to initializeSuccessors().
          • Decoupled rendering phase from finalize phase, converted references to normal successor/predecessor relationships.
          • Converted RecycleUtils to use a concurrent queue instead of maintaining separate queues per thread.
          • Refactored LifecyclePhaseFactory and LifecycleTaskFactory to use RecycleUtils instead of internal recycling mechanisms.
          Show
          Mark Fyffe (Inactive) added a comment - Completed thread pool configuration and phase queueing algorithm. Several clean-up items following recent refactoring accompany this update. View lifecycle is now controlled by the following configuration parameters: rice.krad.lifecycle.trace - enables the logging of processing data related to lifecycle phase processing. This property is particularly useful for troubleshooting asynchronous operation. Default is false. rice.krad.lifecycle.asynchronous - enables asynchronous phase processing. When set to true, lifecycle phases will be performed using pooled worker threads. When false, the original single-threaded lifecycle process is used. Default is false. rice.krad.lifecycle.asynchronous.minThreads - defines the minimum number of worker threads to maintain when asynchronous processing is enabled. This setting has no effect on single-threaded lifecycle processing. The default setting is 4. rice.krad.lifecycle.asynchronous.minThreads - defines the maximum number of worker threads to allow in the pool when asynchronous processing is enabled. This setting has no effect on single-threaded lifecycle processing. The default setting is 48. rice.krad.lifecycle.asynchronous.timeout - defines the time, in milliseconds, to wait for asynchronous lifecycle processing to complete before giving up. One the timeout has reached, any pending phases will be canceled. Changes related to this feature are: Converted all MessageMap lists to be synchronized. In single-threaded mode, these lists should be effectively thread-local but in multi-threaded mode (including multiple requests), they are important to synchronize as recommended in the API documentation for AutoPopulatingList. Moved importTemplate() calls from the finalize phase to the render phase, since rendering may take place in a different thread, which may have a different rendering context. Restructured prepare() and LifecyclePhaseFactory() methods Split processing details out from ViewLifecycle into the new ViewLifecycleProcessor interface. The original single-threaded behavior is supported by SynchronousViewLifecycleProcessor. The multi-threaded behavior is supported by AsynchronousViewLifecycleProcessor. Converted lifecycle phase tree for bottom-up traversal only. Child and sibling references have been removed in favor of pending counts. This consideration eliminates the need to synchronize on lists during phase complete notification. Phases now have only a single predecessor, rather than a list of mulitple predecssors. Precessor phases are assigned dynamically. Pushed rendering phase creation down to initializeSuccessors(). Decoupled rendering phase from finalize phase, converted references to normal successor/predecessor relationships. Converted RecycleUtils to use a concurrent queue instead of maintaining separate queues per thread. Refactored LifecyclePhaseFactory and LifecycleTaskFactory to use RecycleUtils instead of internal recycling mechanisms.

            People

            • Assignee:
              Mark Fyffe (Inactive)
              Reporter:
              Jerry Neal (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 6 hours Original Estimate - 6 hours
                6h
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 1 day, 2 hours
                1d 2h

                  Agile

                    Structure Helper Panel