This ticket outlines necessary improvements to the framework's event handling to resolve timing-related issues and prevent race conditions.
1. Make fireChangeEvent Synchronous
Problem:
The fireChangeEvent method in src/form/field/ComboBox.mjs is asynchronous, which has been identified as the root cause of bugs in the Covid application. Dependent logic executes before the component's value is updated, leading to state inconsistencies.
Solution:
Refactor fireChangeEvent to be fully synchronous. This ensures that when the change event is fired, its listeners are executed immediately, guaranteeing that the component's state is consistent.
Files to Change:
src/form/field/ComboBox.mjs
- Potentially
src/form/field/Base.mjs where the original method is defined.
2. Use delayable for Expensive Calculations in Event Handlers
Problem:
In components with expensive event handlers, such as examples/grid/bigData/ControlsContainer.mjs, rapid-firing events can trigger heavy calculations before the input field's value has been updated in the component's state. This can lead to race conditions or calculations being performed with stale data.
Solution:
Apply a delayable configuration to buffer the execution of event handlers that trigger these calculations. This ensures that there is a slight delay (e.g., one frame), allowing the component's input value and state to be updated before the expensive logic runs.
Example from examples/grid/bigData/ControlsContainer.mjs:
static delayable = {
onAmountColumnsChange : {type: 'buffer', timer: 30},
onAmountRowsChange : {type: 'buffer', timer: 30},
onBufferColumnRangeChange: {type: 'buffer', timer: 30},
onBufferRowRangeChange : {type: 'buffer', timer: 30}
}
Action Items
- Modify
fireChangeEvent in src/form/field/ComboBox.mjs and any relevant base classes to be synchronous.
- Verify the fix in the Covid application.
- Review components with performance-intensive event handlers and apply the
delayable pattern as needed.
This ticket outlines necessary improvements to the framework's event handling to resolve timing-related issues and prevent race conditions.
1. Make
fireChangeEventSynchronousProblem: The
fireChangeEventmethod insrc/form/field/ComboBox.mjsis asynchronous, which has been identified as the root cause of bugs in the Covid application. Dependent logic executes before the component's value is updated, leading to state inconsistencies.Solution: Refactor
fireChangeEventto be fully synchronous. This ensures that when thechangeevent is fired, its listeners are executed immediately, guaranteeing that the component's state is consistent.Files to Change:
src/form/field/ComboBox.mjssrc/form/field/Base.mjswhere the original method is defined.2. Use
delayablefor Expensive Calculations in Event HandlersProblem: In components with expensive event handlers, such as
examples/grid/bigData/ControlsContainer.mjs, rapid-firing events can trigger heavy calculations before the input field's value has been updated in the component's state. This can lead to race conditions or calculations being performed with stale data.Solution: Apply a
delayableconfiguration to buffer the execution of event handlers that trigger these calculations. This ensures that there is a slight delay (e.g., one frame), allowing the component's input value and state to be updated before the expensive logic runs.Example from
examples/grid/bigData/ControlsContainer.mjs:static delayable = { onAmountColumnsChange : {type: 'buffer', timer: 30}, onAmountRowsChange : {type: 'buffer', timer: 30}, onBufferColumnRangeChange: {type: 'buffer', timer: 30}, onBufferRowRangeChange : {type: 'buffer', timer: 30} }Action Items
fireChangeEventinsrc/form/field/ComboBox.mjsand any relevant base classes to be synchronous.delayablepattern as needed.