Repository navigation
perf: skip unchanged organization writes in data-sink member updates - #5164
Conversation
findOrCreateOrganization rewrote every organization it found: the identity and attribute upserts ran on every call and markOrgAttributeDefault updated every attribute row of its name. It now reads the stored attributes and identities once, works out which writes would change anything, and returns before taking the lock when none would. markOrgAttributeDefault also skips rows whose flag is already right. Refs linuxfoundation/lfx-cdp-insights-ops#969 Signed-off-by: Uroš Marolt <uros@marolt.me>
PR SummaryMedium Risk Overview When a change is needed, behavior stays the same: optional lock, re-read + re-plan after lock, then the existing update/upsert/default writes. New helpers Reviewed by Cursor Bugbot for commit bcf5717. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
🟡 Changes recommended
Concurrent updates without organization locking can leave multiple attributes marked as default or skip requested identity-verification changes based on stale state.
2 open issues
What changed in this PR
This PR reduces unnecessary organization writes in the shared data-access layer, primarily improving data-sink member updates while also affecting enrichment and public API callers.
Changes:
- Reads stored attributes and identities together to plan updates and skip unchanged organizations before locking.
- Rechecks state after acquiring the optional organization lock and executes only planned writes.
- Adds identity and attribute comparison helpers and filters default-flag updates to changed rows.
| File | Description |
|---|---|
services/libs/data-access-layer/src/organizations/identities.ts |
Adds identity comparison helpers and reuses identity matching in upserts. |
services/libs/data-access-layer/src/organizations/base.ts |
Plans organization updates and skips unnecessary locks and writes. |
services/libs/data-access-layer/src/organizations/attributes.ts |
Adds attribute comparisons and limits default-flag updates to changed rows. |
Review effort: Balanced
The writes after the first read used decisions taken from that read. Without the per-organization lock another transaction could change the organization meanwhile, so a skipped identity or default write could leave its change unapplied, and two concurrent default changes could both keep their row. Unchanged organizations still return early; otherwise the identity and attribute upserts and the default marking run as before. Refs linuxfoundation/lfx-cdp-insights-ops#969 Signed-off-by: Uroš Marolt <uros@marolt.me>

Summary
findOrCreateOrganizationrewrote every existing organization it found: the identity and attribute upserts ran on every call, andmarkOrgAttributeDefaultupdated every attribute row of its name without checking whether the flag changed. Most organizations arrive unchanged, so almost all of these were no-op writes. data-sink-worker runs without transactions, so each of them was its own commit.This PR works out which writes would change anything and skips the rest.
Changes
findOrCreateOrganizationreads its attributes and identities in one query, a single-round-trip combination of whatfindOrgAttributesandfetchOrgIdentitiesreturn. It then checks whether any write would change something: the organization update, the identity upsert, the attribute upsert or the default flags. If none would, it returns before taking the per-organization lock.prepareOrganizationDatarewrites the default flags of the attributes it's given, so the check runs on a copy and compares with what is stored.Local end-to-end runs against main (b440cf5), on 92.5k real github/git results and 39,659 real meetings activities seeded read-only from prod:
orgAttributesupdatesorgAttributesupdates (pass 1)Inserts and the writes to
organizationsandorganizationIdentities, the tables that are replicated, are the same as on main. Every table has the same rows and columns as main, including the default flags, and so do the Kafka activity messages, search-sync messages and Redis keys. The only differences are generated ids, timestamps, and one organization whose payload order varies between runs of main as well (linuxfoundation/lfx-cdp-insights-ops#972).Type of change
Related issue
Closes linuxfoundation/lfx-cdp-insights-ops#969