-
-
Notifications
You must be signed in to change notification settings - Fork 278
fix: fix concurrency issue: do not merge head snapshot/version requests fr… #2580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…om different tenants. May be related to Permify#2573.
WalkthroughTwo singleflight decorator files are modified to use tenantID as the deduplication key instead of an empty string in HeadSnapshot and HeadVersion methods, changing request deduplication scope from global to per-tenant. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
internal/storage/decorators/singleflight/data_reader.go(1 hunks)internal/storage/decorators/singleflight/schema_reader.go(1 hunks)
🔇 Additional comments (1)
internal/storage/decorators/singleflight/data_reader.go (1)
57-57: Verification confirmed: singleflight decorators are correctly implemented.The codebase search found no instances of empty string keys in singleflight patterns. Both singleflight decorator files (
data_reader.goandschema_reader.go) correctly usetenantIDas the deduplication key, properly scoping operations by tenant. No similar issues exist elsewhere.
| // HeadSnapshot - Reads the latest version of the snapshot from the repository. | ||
| func (r *DataReader) HeadSnapshot(ctx context.Context, tenantID string) (token.SnapToken, error) { | ||
| rev, _, err := r.group.Do(ctx, "", func(ctx context.Context) (token.SnapToken, error) { | ||
| rev, _, err := r.group.Do(ctx, tenantID, func(ctx context.Context) (token.SnapToken, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical fix: Proper tenant isolation in singleflight deduplication.
This change correctly scopes the singleflight deduplication to per-tenant instead of global. Previously, using an empty string as the key would cause concurrent HeadSnapshot requests from different tenants to be merged into a single underlying call, returning the same snapshot token to all tenants. This violated tenant isolation and could lead to authorization checks being performed against the wrong tenant's data.
The fix appropriately uses tenantID as the singleflight key, mirroring the same correction made in schema_reader.go for HeadVersion. This ensures that only concurrent requests for the same tenant are deduplicated.
🤖 Prompt for AI Agents
In internal/storage/decorators/singleflight/data_reader.go around line 57, the
singleflight key is incorrectly scoped (empty string) causing cross-tenant
deduplication; change the call to r.group.Do to use tenantID as the key (i.e.,
pass tenantID instead of ""/empty) so concurrent HeadSnapshot requests are
deduplicated per-tenant only, matching the fix in schema_reader.go for
HeadVersion and preserving tenant isolation.
| // HeadVersion - Finds the latest version of the schema. | ||
| func (r *SchemaReader) HeadVersion(ctx context.Context, tenantID string) (version string, err error) { | ||
| rev, _, err := r.group.Do(ctx, "", func(ctx context.Context) (string, error) { | ||
| rev, _, err := r.group.Do(ctx, tenantID, func(ctx context.Context) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical fix: Proper tenant isolation in singleflight deduplication.
This change correctly scopes the singleflight deduplication to per-tenant instead of global. Previously, using an empty string as the key would cause concurrent HeadVersion requests from different tenants to be merged into a single underlying call, resulting in the same version being returned to all tenants regardless of their actual latest versions. This was a critical tenant isolation bug that could lead to incorrect behavior and potential data leakage.
The fix appropriately uses tenantID as the singleflight key, ensuring that only concurrent requests for the same tenant are deduplicated.
🤖 Prompt for AI Agents
In internal/storage/decorators/singleflight/schema_reader.go around line 46, the
singleflight call is using an empty-string key which causes deduplication across
all tenants; change the key to tenantID so deduplication is scoped per-tenant
(i.e., pass tenantID as the key to r.group.Do). Ensure tenantID is the canonical
tenant identifier (string) used throughout this code path and convert it to a
string if necessary, so concurrent HeadVersion requests are only merged for the
same tenant.
…om different tenants.
May be related to #2573.
Summary by CodeRabbit