Skip to content
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

fix concurrent map writes #1732

Merged
merged 3 commits into from
Jan 3, 2024
Merged

Conversation

zkokelj
Copy link
Contributor

@zkokelj zkokelj commented Jan 3, 2024

Why this change is needed

On December 31th Ten Gatewat crashed:

https://app.datadoghq.eu/logs?query=service%3Aobscuro_gateway_sepolia_testnet&cols=host%2Cservice&event=AgAAAYzAOYx5aCAipAAAAAAAAAAYAAAAAEFZekFPWXlYQUFEbFpRQ1pSdFhYZWdBQQAAACQAAAAAMDE4Y2MwOWEtN2VmYy00MWZkLWFiMjgtMjZmNjMxZDIwYWE1&index=%2A&messageDisplay=inline&refresh_mode=paused&stream_sort=time%2Casc&viz=stream&from_ts=1704027600000&to_ts=1704032100000&live=false

What changes were made as part of this PR

Add mutex to avoid concurrent writes to the map

PR checks pre-merging

Please indicate below by ticking the checkbox that you have read and performed the required
PR checks

  • PR checks reviewed and performed

https://github.com/ten-protocol/ten-test/actions/runs/7397025563

Copy link

coderabbitai bot commented Jan 3, 2024

Walkthrough

The recent update introduces thread-safety to the user account management system by integrating a mutex. This ensures that concurrent access to user account operations such as adding, retrieving, and deleting account managers is controlled, preventing potential data races or inconsistencies.

Changes

File Path Changes
.../useraccountmanager/user_account_manager.go Update of the mutex field in the UserAccountManager struct from sync.Mutex to sync.RWMutex for better read-write access control.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • You can directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • You can tag CodeRabbit on specific lines of code or entire files in the PR by tagging @coderabbitai in a comment. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • You can tag @coderabbitai in a PR comment and ask questions about the PR and the codebase. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid.
    • @coderabbitai read the files in the src/scheduler package and generate README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

@zkokelj zkokelj marked this pull request as ready for review January 3, 2024 10:29
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between a0cec15 and 9347e1c.
Files selected for processing (1)
  • tools/walletextension/useraccountmanager/user_account_manager.go (5 hunks)
Additional comments: 5
tools/walletextension/useraccountmanager/user_account_manager.go (5)
  • 6-6: Added sync package to support mutex synchronization.

  • 22-22: Mutex added to the struct to handle synchronization.

  • 37-38: Mutex locking and unlocking implemented correctly using defer to ensure the mutex is always unlocked.

  • 54-55: Mutex synchronization added to ensure thread safety during read operations.

  • 112-113: Mutex locking and unlocking added to protect the map during delete operations.

Comment on lines 34 to 41

// AddAndReturnAccountManager adds new UserAccountManager if it doesn't exist and returns it, if UserAccountManager already exists for that user just return it
func (m *UserAccountManager) AddAndReturnAccountManager(userID string) *accountmanager.AccountManager {
m.mu.Lock()
defer m.mu.Unlock()
existingUserAccountManager, exists := m.userAccountManager[userID]
if exists {
return existingUserAccountManager
Copy link

Choose a reason for hiding this comment

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

Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [19-116]

Please ensure that the PR checklist, as outlined in the project's development operations documentation, is completed and confirmed.

Copy link
Collaborator

@BedrockSquirrel BedrockSquirrel left a comment

Choose a reason for hiding this comment

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

LGTM, optional comment

@@ -47,6 +51,8 @@ func (m *UserAccountManager) AddAndReturnAccountManager(userID string) *accountm
// (we are not loading all of them at startup to limit the number of established connections)
// If a UserAccountManager does not exist for the userID, it returns nil and an error.
func (m *UserAccountManager) GetUserAccountManager(userID string) (*accountmanager.AccountManager, error) {
m.mu.Lock()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Worth using RWMutex and just doing read lock for this read op?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, using RWMutex and m.mu.RLock() here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 9347e1c and 1707cd1.
Files selected for processing (1)
  • tools/walletextension/useraccountmanager/user_account_manager.go (5 hunks)
Additional comments: 4
tools/walletextension/useraccountmanager/user_account_manager.go (4)
  • 6-6: Added sync package to support mutex usage.

  • 22-22: Mutex added to the struct for managing concurrent access.

  • 54-55: Correct usage of mutex for thread-safe access in GetUserAccountManager.

  • 112-113: Correct usage of mutex for thread-safe deletion in DeleteUserAccountManager.

Comment on lines 37 to 38
m.mu.RLock()
defer m.mu.Unlock()
Copy link

@coderabbitai coderabbitai bot Jan 3, 2024

Choose a reason for hiding this comment

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

Mismatched lock and unlock methods; RLock() should be paired with RUnlock().

- defer m.mu.Unlock()
+ defer m.mu.RUnlock()

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
m.mu.RLock()
defer m.mu.Unlock()
m.mu.RLock()
defer m.mu.RUnlock()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Copy link

Choose a reason for hiding this comment

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

@zkokelj Great, thank you for addressing the lock pairing issue.

🎉


New Learnings Added
User: zkokelj
PR: ten-protocol/go-ten#1732
File: tools/walletextension/useraccountmanager/user_account_manager.go:0-0
Timestamp: 2024-01-03T11:07:08.884Z
Learning: The `AddAndReturnAccountManager` method in `user_account_manager.go` should use `RLock()` and `RUnlock()` for read-only operations to ensure proper lock pairing.

If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 1707cd1 and 99bb416.
Files selected for processing (1)
  • tools/walletextension/useraccountmanager/user_account_manager.go (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • tools/walletextension/useraccountmanager/user_account_manager.go

@zkokelj zkokelj merged commit 986f699 into main Jan 3, 2024
2 checks passed
@zkokelj zkokelj deleted the ziga/gateway_fix_concurrent_map_write branch January 3, 2024 13:53
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