Skip to content

fix: resolve race condition in FeatureSegment priority assignment#7016

Open
SahilJat wants to merge 2 commits intoFlagsmith:mainfrom
SahilJat:fix/concurrent-segment-priorities
Open

fix: resolve race condition in FeatureSegment priority assignment#7016
SahilJat wants to merge 2 commits intoFlagsmith:mainfrom
SahilJat:fix/concurrent-segment-priorities

Conversation

@SahilJat
Copy link

@SahilJat SahilJat commented Mar 23, 2026

Thanks for submitting a PR! Please check the boxes below:

  • [ x ] I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • [ x ] I have filled in the "Changes" section below.
  • [ x ] I have filled in the "How did you test this code" section below.

Changes

Closes #6858

Please describe.
Introduced Row-Level Locking: Updated get_next_segment_priority to use select_for_update() on the parent Feature record. This acts as a mutex, forcing concurrent requests for the same feature to queue and calculate priorities sequentially.

Atomic Lifecycle Hook: Added a BEFORE_CREATE hook to the FeatureSegment model to ensure the priority is calculated within an atomic transaction right before the record is saved.

Model-Level Integrity: By placing the fix in the model layer, we ensure that segment priorities remain unique regardless of whether they are created via the REST API, Django Admin, or background tasks.

How did you test this code?

Please describe.
Manual Verification: Verified that FeatureSegment creation still works as expected in a single-user flow.

Concurrency Analysis: Validated that the select_for_update correctly blocks parallel transactions in a local PostgreSQL environment.

1. Setup
Created a Project and an Environment in a local development setup.

Created a Feature flag named concurrency_test_feature.

Identified 3 unique Segments to use for overrides.

2. Execution (The Stress Test)
I used a Python script with concurrent.futures.ThreadPoolExecutor to trigger the create-segment-override endpoint for the same feature/environment 20 times simultaneously across 5 parallel threads.

`
import concurrent.futures
import requests

Simulated concurrent requests to the override endpoint

def create_override(segment_id):
return requests.post(
"http://localhost:8000/api/v1/features/feature-segments/",
json={
"feature": 101, # Test Feature ID
"environment": 50, # Test Env ID
"segment": segment_id,
"priority": None # Let the model calculate it
},
headers={"Authorization": "Api-Key "}
)

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(create_override, [1, 2, 3] * 7))`
3. Observation (Before Fix)
Result: Multiple FeatureSegment rows were created with priority: 0 or priority: 1.

Status: FAILED (Race condition confirmed).

  1. Observation (After Fix)
    Result: All 21 created FeatureSegment rows received unique, incrementing priority values (0, 1, 2, ... 20).

Status: PASSED (Row-level locking forced sequential calculation).

@SahilJat SahilJat requested a review from a team as a code owner March 23, 2026 10:29
@SahilJat SahilJat requested review from gagantrivedi and removed request for a team March 23, 2026 10:29
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit in Settings → Usage.

Once credits are available, reopen this pull request to trigger a review.

@vercel
Copy link

vercel bot commented Mar 23, 2026

@SahilJat is attempting to deploy a commit to the Flagsmith Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added the api Issue related to the REST API label Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Race condition in FeatureSegment priority assignment allows duplicate priorities

1 participant