[Streams] Only mark _changes as true when values are meaningful#250806
[Streams] Only mark _changes as true when values are meaningful#250806flash1293 merged 20 commits intoelastic:mainfrom
Conversation
Fixes elastic#241300 When creating a new stream with empty/default values for properties like `fields`, `processing.steps`, `routing`, etc., the change tracking logic was unconditionally marking all properties as changed. This caused unnecessary validation and ES actions (like rollovers) to execute. This fix updates the `doHandleUpsertChange` method in both WiredStream and ClassicStream to only mark a property as changed when: - For new streams: the value is non-empty/non-default - For existing streams: the value actually differs from the previous state Properties affected: - WiredStream: ownFields, routing, processing, lifecycle, settings, failure_store - ClassicStream: processing, lifecycle, settings, field_overrides, failure_store Co-authored-by: Cursor <cursoragent@cursor.com>
|
/ralph the change looks good, but the code you wrote is very repetitive. Identify a way to make it a bit more DRY for the pattern of the check (if it's a create, check whether there is something, if it's a change, check whether something got changed). |
Extract repetitive pattern for determining if a stream property changed into a reusable helper function. This makes the code more DRY by abstracting the logic: for existing streams, check if values changed; for new streams, check if value is meaningful/non-empty.
|
Refactored the change detection logic to be more DRY by introducing a Changes:
The helper abstracts the common pattern:
Written by cursor, wait for @flash1293 to chime in |
|
Pinging @elastic/obs-onboarding-team (Team:obs-onboarding) |
|
This is ready for human review |
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # x-pack/platform/plugins/shared/streams/server/lib/streams/state_management/streams/classic_stream.ts # x-pack/platform/plugins/shared/streams/server/lib/streams/state_management/streams/wired_stream.ts
| const isExistingStream = !!startingStateStreamDefinition; | ||
|
|
||
| this._changes.ownFields = computeChange( | ||
| isExistingStream, |
There was a problem hiding this comment.
Perhaps we can consider passing an object with descriptive keys to computeChange so it's more immediately apparent what these arguments represent. Wdyt?
CoenWarmer
left a comment
There was a problem hiding this comment.
Code looks good, left one comment to consider
|
Fair point - /ralph can you change the interface of computeChange to an options object so it's clear what parameter means what? |
Changed the interface of computeChange from positional parameters to an options object with descriptive keys (isExistingStream, hasMeaningfulValue, hasChanged) for improved readability at call sites. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Changed the interface of Changes:
Example call site before: computeChange(isExistingStream, hasValue, () => !_.isEqual(a, b))Example call site after: computeChange({
isExistingStream,
hasMeaningfulValue: hasValue,
hasChanged: () => !_.isEqual(a, b),
})Written by cursor, wait for @flash1293 to chime in |
|
The refactor looks good to me, any other thoughts @CoenWarmer ? |
|
@CoenWarmer should be good for another look |
|
LGTM |
Update test files to use proper type annotations instead of `as any` casts to comply with the no-explicit-any ESLint rule that was added to the streams plugins. Co-authored-by: Cursor <cursoragent@cursor.com>
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]
History
|
…tic#250806) ## 🍒 Summary Fixes unnecessary validation and Elasticsearch actions (like rollovers) when creating streams with empty/default property values. Closes elastic#241300 ## 🛠️ Changes - Updated `WiredStream.doHandleUpsertChange()` to only mark properties as changed when values are meaningful: - `ownFields`: only true when `fields` object is non-empty - `routing`: only true when routing rules array is non-empty - `processing`: only true when `processing.steps` array is non-empty - `lifecycle`: only true when lifecycle is not `inherit` (default) - `settings`: only true when `settings` object is non-empty - `failure_store`: only true when failure_store is not `inherit` (default) - Updated `ClassicStream.doHandleUpsertChange()` with the same pattern: - `processing`: only true when `processing.steps` array is non-empty - `lifecycle`: only true when lifecycle is not `inherit` (default) - `settings`: only true when `settings` object is non-empty - `field_overrides`: only true when `field_overrides` object is non-empty - `failure_store`: only true when failure_store is not `inherit` (default) - Added comprehensive unit tests for both `WiredStream` and `ClassicStream` covering: - New stream creation with empty vs non-empty values - Existing stream updates with actual vs no changes - Edge cases for all property types ## 🎙️ Prompts - Investigate the root cause of unnecessary rollovers when creating streams - Implement conditional change tracking for empty/default values - Add unit tests covering all change tracking scenarios - Validate with integration tests 🤖 This pull request was assisted by Cursor --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
🍒 Summary
Fixes unnecessary validation and Elasticsearch actions (like rollovers) when creating streams with empty/default property values.
Closes #241300
🛠️ Changes
Updated
WiredStream.doHandleUpsertChange()to only mark properties as changed when values are meaningful:ownFields: only true whenfieldsobject is non-emptyrouting: only true when routing rules array is non-emptyprocessing: only true whenprocessing.stepsarray is non-emptylifecycle: only true when lifecycle is notinherit(default)settings: only true whensettingsobject is non-emptyfailure_store: only true when failure_store is notinherit(default)Updated
ClassicStream.doHandleUpsertChange()with the same pattern:processing: only true whenprocessing.stepsarray is non-emptylifecycle: only true when lifecycle is notinherit(default)settings: only true whensettingsobject is non-emptyfield_overrides: only true whenfield_overridesobject is non-emptyfailure_store: only true when failure_store is notinherit(default)Added comprehensive unit tests for both
WiredStreamandClassicStreamcovering:🎙️ Prompts
🤖 This pull request was assisted by Cursor