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

Use repeatable read for pnl tick generation. #2578

Merged
merged 1 commit into from
Nov 18, 2024

Conversation

vincentwschau
Copy link
Contributor

@vincentwschau vincentwschau commented Nov 16, 2024

Changelist

By default all transactions in postgres use the read committed isolation level. This means that any SELECT within a transaction will only see data that was committed before the select was run. However, this means that SELECTs within a transaction done at different times may see different data. This is an issue for the PnL task which gets data from the transfers table and the perpetual_positions table to determine the PnL snapshot of a subaccount, as there can be a race condition between reading the transfers and perpetual positions if ender is updating both tables.
Instead we should use the repeatable read transaction isolation level, that guarantees within a transaction all SELECTs will read the same snapshot of data. We only use this for the read-only transaction in the pnl task to ensure no rollbacks / retries need to be added.

Transaction isolation level reference

Test Plan

Unit tests, running in a deployed environment.

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

Summary by CodeRabbit

  • New Features

    • Enhanced transaction management for creating PNL ticks, ensuring more consistent data reads.
  • Bug Fixes

    • Improved error handling during the fetching of PNL ticks to ensure better logging and recovery.

@vincentwschau vincentwschau requested a review from a team as a code owner November 16, 2024 18:59
Copy link
Contributor

coderabbitai bot commented Nov 16, 2024

Walkthrough

The changes involve modifying the runTask function in create-pnl-ticks.ts to include a new import, IsolationLevel, from the @dydxprotocol-indexer/postgres module. The transaction isolation level is now set to REPEATABLE_READ after starting a transaction, enhancing read consistency. Comments have been updated for clarity, while the overall structure and error handling of the function remain unchanged. This adjustment aims to improve transaction management during the creation of Profit and Loss (PnL) ticks.

Changes

File Path Change Summary
indexer/services/roundtable/src/tasks/create-pnl-ticks.ts Added import for IsolationLevel, modified runTask to set transaction isolation level to REPEATABLE_READ, and updated comments for clarity.

Possibly related PRs

Suggested labels

indexer

Suggested reviewers

  • tqin7

🐇 In the garden where numbers play,
A new import has come to stay.
With REPEATABLE_READ, we keep things neat,
In ticks of PnL, our work's complete.
Errors caught, and clarity shines,
In the world of finance, all aligns! 🌼


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c26c8b8 and 987cc1f.

📒 Files selected for processing (1)
  • indexer/services/roundtable/src/tasks/create-pnl-ticks.ts (2 hunks)
🔇 Additional comments (3)
indexer/services/roundtable/src/tasks/create-pnl-ticks.ts (3)

5-5: LGTM: Import addition is appropriate

The IsolationLevel import is correctly placed with other postgres-related imports and is necessary for the transaction isolation level modification.


Line range hint 60-61: Document REPEATABLE_READ requirements in getPnlTicksCreateObjects

Since getPnlTicksCreateObjects is now called within a REPEATABLE_READ transaction, it should be documented whether this function:

  1. Requires this isolation level for correctness
  2. Makes any assumptions about the transaction isolation level
  3. Has any specific ordering requirements for its database queries

Let's check the implementation:

#!/bin/bash
# Description: Analyze getPnlTicksCreateObjects implementation

# Look for database queries in the function
ast-grep --pattern 'function getPnlTicksCreateObjects($_) {
  $$$
}'

# Check for any explicit transaction isolation requirements in comments
rg -B 2 "getPnlTicksCreateObjects"

54-57: Verify performance impact of REPEATABLE_READ isolation level

The implementation correctly sets the isolation level to REPEATABLE_READ immediately after starting the transaction, which will ensure consistent reads across the transaction as intended. However, this higher isolation level might impact performance due to additional locking overhead.

Consider monitoring these metrics after deployment:

  1. Transaction duration
  2. Lock contention
  3. Transaction rollback rate

Let's verify the transaction usage pattern:

✅ Verification successful

Based on the shell script results, I can now provide a final response:

REPEATABLE_READ isolation level is appropriate for PNL tick creation

The implementation correctly uses REPEATABLE_READ isolation level for the following reasons:

  • The transaction reads from multiple tables to compute PNL ticks (BlockTable, SubaccountTable) where consistency between reads is critical
  • Other services use different isolation levels based on their needs (READ_UNCOMMITTED for trading rewards, READ_COMMITTED for caches)
  • The transaction is short-lived and focused on computing PNL ticks
  • The code includes proper error handling and rollback mechanisms

The performance impact should be minimal because:

  • The transaction scope is limited to reading data and creating PNL tick objects
  • The actual insertion of PNL ticks happens in separate transactions with chunked batches
  • The code includes performance monitoring via stats.timing
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other transaction isolation level settings and potential conflicts

# Look for other transaction isolation level settings
rg -A 5 "setIsolationLevel" 

# Look for concurrent operations on transfers and perpetual_positions tables
ast-grep --pattern 'Transaction.start()' 

Length of output: 3975


Script:

#!/bin/bash
# Let's check for transaction isolation level settings and transaction patterns

# Look for transaction isolation level settings
rg -A 5 "IsolationLevel\." --type ts

# Look for transaction start patterns with context
rg -B 2 -A 5 "Transaction\.start\(\)" --type ts

# Look for tables accessed within the transaction
rg -A 10 "getPnlTicksCreateObjects" indexer/services/roundtable/src/helpers/pnl-ticks-helper.ts

Length of output: 21643


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

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@vincentwschau vincentwschau merged commit 898fb93 into main Nov 18, 2024
16 checks passed
@vincentwschau vincentwschau deleted the vincentc/pnl-repeatable-read branch November 18, 2024 15:56
mergify bot pushed a commit that referenced this pull request Nov 18, 2024
vincentwschau added a commit that referenced this pull request Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants