Track multiple sources per vanflow record during purge. - #2572
Conversation
📝 WalkthroughWalkthroughThe store now tracks every source that asserts a record. Source purge removes one assertion and deletes the record only when no sources remain. StatusSync, Collector, and process reconciliation use the updated store behavior. ChangesSource affinity purge
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant StatusSync
participant Collector
participant syncMapStore
participant SourceIndexer
StatusSync->>syncMapStore: RemoveSource(source)
Collector->>syncMapStore: RemoveSource(source)
syncMapStore->>SourceIndexer: Find entries indexed for source
syncMapStore->>syncMapStore: Remove source assertion
syncMapStore-->>StatusSync: Return removed count
syncMapStore-->>Collector: Return removed count
Merge Risk: 🟡 Moderate · up to A caller can corrupt source membership and cause purge to retain or remove records incorrectly. Clone source metadata on all read paths before merging. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: cefe1daa-79be-40ed-99d3-3271ce3510b4
📒 Files selected for processing (5)
cmd/network-observer/internal/collector/collector.gointernal/flow/status.gopkg/vanflow/store/store.gopkg/vanflow/store/syncmap.gopkg/vanflow/store/syncmap_test.go
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.
| type Metadata struct { | ||
| LastUpdate time.Time | ||
|
|
||
| // Source is the first source that asserted this record. |
There was a problem hiding this comment.
Looks like the only place this is used (outside of store) is the network observer process mapping stuff. I think it'd be better to stop carrying around a Source field and to add a HasSource(source SourceRef) bool method instead - the process controller thing will work fine that way.
| m.ensureSources() | ||
| for i, existing := range m.Sources { | ||
| if sourceRefEqual(existing, source) { | ||
| m.Sources = append(m.Sources[:i], m.Sources[i+1:]...) |
There was a problem hiding this comment.
I think we need to be careful to avoid race conditions/consistency problems here and copy the slice instead of mutating/shifting its contents. (maybe in AddSource too?) Store methods return Entry/Metadata by value on purpose so that the caller's copy doesn't get changed out from under it. Now with a slice (instead of a string) and the shared backing array it points to, mutating that slice's contents might break guarantees.
Maybe something like this instead?
i := slices.Index(m.Sources, source)
if i < 0 {
return false
}
m.Sources = slices.Delete(slices.Clone(m.Sources), i, i+1)
...
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/vanflow/store/store.go (1)
21-21: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winClone
Sourcesat everysyncMapStoreownership boundary.
Replacestores caller-providedEntryvalues without cloning.Get,List, andIndexreturn entries that share the store'sSourcesbacking arrays. Event callbacks receive the same shared arrays. A caller can changeentry.Sources[i]without a store method, soSourceIndexremains stale andRemoveSourcecan miss records.Clone entries when
syncMapStoreaccepts, returns, or dispatches them. Add regression tests for mutation throughGet,Index, and event handlers.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: cbdad9f7-dbb0-4f6a-91e9-7b9faa532620
📒 Files selected for processing (4)
cmd/network-observer/internal/collector/processes.gopkg/vanflow/store/store.gopkg/vanflow/store/syncmap.gopkg/vanflow/store/syncmap_test.go
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/vanflow/store/store.go (1)
21-21: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftClone
Sourceson every read path.Get,List, andIndexreturn shallowEntrycopies, whilecloneEntryis not used there. A caller can mutateEntry.Sources, changingm.itemswithout updating the source index. ReturncloneEntryresults from all three methods and add mutation-isolation coverage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: 678528cf-7999-47f9-a7a0-a3db1ad2ac39
📒 Files selected for processing (4)
cmd/network-observer/internal/collector/processes.gopkg/vanflow/store/store.gopkg/vanflow/store/syncmap.gopkg/vanflow/store/syncmap_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
- pkg/vanflow/store/syncmap.go
- pkg/vanflow/store/syncmap_test.go
- pkg/vanflow/store/store.go
- cmd/network-observer/internal/collector/processes.go
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.
Fixes #2568
Summary by CodeRabbit