Narrow distribution locks with safe base_path protection - #7896
Conversation
|
Can you add a changelog for this issue? #3322 |
c74e46f to
6faf576
Compare
|
Done :) |
|
Not sure what is up with lint, maybe try rebasing with main. Also can you add |
6faf576 to
cb2a1be
Compare
|
I'd like it to be backported to at least the release(s) that are part of Satellite 6.19.z. |
951ea58 to
b4d28e3
Compare
mdellweg
left a comment
There was a problem hiding this comment.
I am a tiny bit concerned about Zero Downtime Upgrades here.
An old task (dispatched before this change) updating a distribution would only lock on the domain:distributions and a new one only on the single distribution.
Since distributions themselves are rather shallow, I cannot think about a situation where this collision leads to real world impacts. But my lack of imagination here is no guarantee for correctness.
| """ | ||
| Reserve the narrowest safe lock for async distribution operations. | ||
|
|
||
| Creates, deletes, and base_path changes still lock the domain-wide distributions resource |
There was a problem hiding this comment.
Maybe add a statement that "base_path overlap validation" is the main concern why this function even exists.
I'm wondering if we can safely assume that deleting a distribution will never violate base_path overlaps?
There was a problem hiding this comment.
Yes, that is the main reason this logic exists, and I can make that clearer in the docstring.
I would still keep deletes on the broader lock. A delete does not create an overlap by itself, but it does release a base_path, so it is still part of the same domain-wide consistency concern as creates and moves.
Thanks, I think this is the main caveat in the current approach. From our look at the code, we see two ways to address the ZDU concern:
Both approaches would keep the current concurrency improvement while restoring compatibility with older broad-lock tasks during mixed-version upgrades. |
But only if it doesn't actually change the base path, right? Tasks that do touch base_path would retain the domain:distributions lock. That seems OK. |
|
If I’m understanding correctly, the mixed-version caveat would only apply to updates whose effective Creates, deletes, and updates that do change So the remaining ZDU concern would be narrower: it would apply only to ordinary unchanged- If that matches your reading as well, would you prefer to keep the current scoped change, or would you want the mixed-version case addressed in this PR too? |
|
I am certain that destroying a distribution can only release a base_path and so cannot even conflict with a prefixed-overlapped base_path that is created at the same time around. (Either the create fails, or the delete succeeded first. In any case the result is consistent wrt the overlap constraint.) As for the ZDU concerns, I think if we aquire the existing domain-scoped lock shared, and introduce a new (uhhh, regrets...) domain-scoped-base-path lock to use alongside the specific entity lock, we'd be completely safe. |
|
Thank you both, this discussion has been very helpful. My current understanding is that:
At this point, I can see a few possible directions for the PR:
I would appreciate your guidance on which direction you would prefer for this PR. |
|
Ok, we had even more discussion about the bigger picture. And distributions in some plugins may not actually be as shallow as we wish. So let's play this safe:
Outlook: |
|
Thank you, this is very helpful. My understanding is that the preferred direction would be:
Please let me know if that matches your understanding of the problem and the intended solution. Also, if that direction looks right, would you like me to work on that rework in this PR, or would you prefer to handle that part yourselves? |
|
Yes, please. |
|
Yes, to which option? :) |
|
To make this Pr ready with the safe way. Ignore the "outlook" part. |
|
I pushed a rework of the PR along the safe direction discussed above. My intent with this update was to:
I also updated the focused reservation test to cover the new lock shape. Could you please take a look and let me know whether this matches your expectations for the safe version? |
|
I put together the alternative implementation on a separate comparison branch so we can sanity-check the shape before changing this PR. Branch: From our look at the code, this keeps the same reservation semantics as the current version, but moves the If this direction matches better what you had in mind, I can rework the main PR branch to follow it. |
|
That looks a lot cleaner, so yes. Can you merge that and I will review on top of it? |
|
I merged that approach into the main PR branch, so this PR now uses the generic The behavior should stay the same as in the comparison branch; this just moves the dispatch plumbing back into the shared async mixins. Happy to hear any follow-up feedback on top of this version. |
|
I think we are there. Please squash all commits into one, now. |
…ection Reserve per-distribution locks for ordinary updates while serializing creates and base_path changes on a dedicated domain-scoped distribution.base_path resource. Keep the legacy domain:distributions reservation in shared mode for mixed-version upgrade safety, and move the shared-resource plumbing into the generic async mixins so publication.py only defines the distribution-specific lock policy. Co-authored-by: Cursor <cursoragent@cursor.com>
4fb02fb to
c8aedcd
Compare
|
I squashed the branch into a single commit and updated the commit message to reflect the final direction. This PR should now be ready for review on top of the generic |
Backport to 3.85: 💔 cherry-picking failed — conflicts found❌ Failed to cleanly apply d57f727 on top of patchback/backports/3.85/d57f7275e4fb599f5488fe207fb1c8ae4472f4f5/pr-7896 Backporting merged PR #7896 into main
🤖 @patchback |
Backport to 3.105: 💚 backport PR created✅ Backport PR branch: Backported as #7955 🤖 @patchback |
Backport to 3.115: 💚 backport PR created✅ Backport PR branch: Backported as #7956 🤖 @patchback |
Problem
Async distribution CUD operations currently reserve the domain-wide
pdrn:<domain>:distributionsresource too broadly. For ordinary updatesthat leave
base_pathunchanged, this serializes unrelatedpulpcore.app.tasks.base.ageneral_updatetasks behind a lock they do notneed.
This showed up as a bottleneck during capsule sync, where many
RefreshDistributionupdates can run at once but end up waiting on thesame reservation.
What this changes
This patch narrows distribution task reservations while keeping the
base_pathnamespace protected in the safer way discussed in review:base_pathunchanged reserve only thedistribution instance
base_pathalsoreserve a dedicated domain-scoped
distribution.base_pathresourcedistribution.base_pathlockdomain:distributionsreservation is still added in sharedmode for mixed-version upgrade compatibility
The implementation also handles partial
PATCHrequests correctly byfalling back to
instance.base_pathwhenbase_pathis omitted from therequest body.
As part of the final cleanup, the
shared_resourcesplumbing now lives inthe generic async mixins in
base.py, whilepublication.pyonly definesthe distribution-specific lock policy.
Test coverage
Adds a functional test covering the reservation behavior for:
base_pathin the payloadbase_pathbase_pathPerformance notes
Tested with Satellite 6.20 Stream,
~175 capsules, 15 Pulp workers.
For completed
pulpcore.app.tasks.base.ageneral_updatetasks, lock usageshifted from all domain-wide reservations to a mix of domain and
instance-scoped reservations:
Block wait times improved substantially:
These results are consistent with removing unnecessary serialization for
ordinary distribution updates while preserving explicit protection when the
base_pathnamespace can change.