You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Data source stream silently discards changes with ChangedBy == null (potential silent write loss) #678
Found while fixing the DataTest flakes (#676) and deliberately not fixed there — reachability could not be proven, but the shape is silent data loss.
The filter
TypeSourceBasedUnpartitionedDataSource.SetupDataSourceStream filters the change feed with:
Where(x =>isFirst||(x.ChangedByis not null&& …))
Any change with ChangedBy == nullafter the first emission is discarded — never persisted, never logged, no warning. And UpdateStream's Full path constructs exactly such a ChangeItem (the 3-arg constructor leaves ChangedBy == null).
Why it's worth a look
If that path is reachable on a data-source stream, a write is silently dropped: the workspace shows the new state, the caller sees success, and the store never receives it. That is the same class as the two data-loss bugs fixed tonight (#665 owner-recycle rollback, #675 GitSync server-addition prune) — in both, the silence was what made the defect survive so long.
Two questions to settle:
Is the ChangedBy == null path actually reachable for a data-source stream (as opposed to a client/reduced stream where the filter is presumably intended)?
If it is reachable and dropping is correct, should it at least log — a discarded write with no trace is indistinguishable from a write that never happened.
Also noted in the same area
WithUpdate's transform is a no-op: Synchronize discards the return value of ITypeSource.Update, so the documented "transforms the collection before it is stored" only ever takes effect as a side effect on the passed instance.
DataChangeStatus.Committed is returned before the write-back runs. Consistent with the design (persistence is dispatched to a separate hub), but the name over-promises — callers reasonably read "Committed" as "durable".
Activity
Merge pull request #887 from Systemorph/fix/678-unattributed-change-drop