Skip to content

[management] Remove store locks #4038

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

pascal-fischer
Copy link
Collaborator

Describe your changes

Issue ticket number and link

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • Extended the README / documentation, if necessary

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

@Copilot Copilot AI review requested due to automatic review settings June 23, 2025 16:16
Copy link

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR removes explicit per-account and per-entity locking (AcquireWriteLockByUID/AcquireReadLockByUID) across the management server, streamlining store interface and default account manager methods.

  • Eliminated calls to AcquireWriteLockByUID/AcquireReadLockByUID in DefaultAccountManager and router/resource/peer/network managers.
  • Removed these lock methods from the Store interface.
  • Retained only AcquireGlobalLock for coarse-grained locking.

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
management/server/user.go Dropped per-account write locks from user operations
management/server/store/store.go Removed lock methods from Store interface
management/server/setupkey.go Deleted write-lock wrappers around setup keys
management/server/route.go Removed per-account locks from route CRUD
management/server/posture_checks.go Dropped locks in posture check save/delete
management/server/policy.go Removed write locks around policy save/delete
management/server/peer.go Eliminated read/write locks in peer flows
management/server/networks/… Deleted per-account locks in routers/resources/managers
management/server/nameserver.go Removed write locks in nameserver group operations
management/server/integrated_validator.go Dropped write lock around validator update
management/server/group.go Deleted locks in group management methods
management/server/account.go Removed locks in account settings/jobs and sync routines
Comments suppressed due to low confidence (2)

management/server/user.go:28

  • Concurrent operations on account-level data now lack explicit locks. It's advisable to add tests that simulate concurrent creation/invitation of users to ensure data consistency.
func (am *DefaultAccountManager) createServiceUser(ctx context.Context, accountID string, initiatorUserID string, role types.UserRole, serviceUserName string, nonDeletable bool, autoGroups []string) (*types.UserInfo, error) {

@@ -26,9 +26,6 @@ import (

// createServiceUser creates a new service user under the given account.
func (am *DefaultAccountManager) createServiceUser(ctx context.Context, accountID string, initiatorUserID string, role types.UserRole, serviceUserName string, nonDeletable bool, autoGroups []string) (*types.UserInfo, error) {
Copy link
Preview

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

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

Removing per-account write locks in critical sections like createServiceUser may introduce race conditions. Consider using transaction-level locking or AcquireGlobalLock to preserve atomicity of account modifications.

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@crn4 crn4 left a comment

Choose a reason for hiding this comment

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

I added some comments where I think better to add a transaction. let's discuss

@@ -640,8 +632,6 @@ func (am *DefaultAccountManager) isCacheCold(ctx context.Context, store cacheSto

// DeleteAccount deletes an account and all its users from local store and from the remote IDP if the requester is an admin and account owner
func (am *DefaultAccountManager) DeleteAccount(ctx context.Context, accountID, userID string) error {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()
account, err := am.Store.GetAccount(ctx, accountID)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that here we can have possible race. somewhere between user are being removed and actual removal of an account, still possible that user could be created

Comment on lines -1010 to -1012
unlockAccount := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlockAccount()

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that here better to add a transaction

Comment on lines -107 to -109
unlock := m.store.AcquireWriteLockByUID(ctx, network.AccountID)
defer unlock()

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that we need to add a transaction here, as some changes could be made between select and actual update

@@ -55,8 +55,6 @@ type SetupKeyUpdateOperation struct {
// and adds it to the specified account. A list of autoGroups IDs can be empty.
func (am *DefaultAccountManager) CreateSetupKey(ctx context.Context, accountID string, keyName string, keyType types.SetupKeyType,
expiresIn time.Duration, autoGroups []string, usageLimit int, userID string, ephemeral bool, allowExtraDNSLabels bool) (*types.SetupKey, error) {
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()

Copy link
Contributor

Choose a reason for hiding this comment

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

seems that here we have a transaction which runs another transaction (SaveSetupKey). this is not about the removal of the lock, but maybe worth it to change

@@ -227,9 +221,6 @@ func (am *DefaultAccountManager) DeleteUser(ctx context.Context, accountID, init
return status.Errorf(status.InvalidArgument, "self deletion is not allowed")
}

unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()

initiatorUser, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthShare, initiatorUserID)
Copy link
Contributor

Choose a reason for hiding this comment

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

I propose to add a transaction here

Comment on lines -331 to -333
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that better to add here too

Comment on lines -382 to -384
unlock := am.Store.AcquireWriteLockByUID(ctx, accountID)
defer unlock()

Copy link
Contributor

Choose a reason for hiding this comment

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

and here. we can have a race if these methods will be called concurrently

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants