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

remove errBadConnNoWrite and markBadConn #1583

Closed
wants to merge 2 commits into from

Conversation

methane
Copy link
Member

@methane methane commented May 16, 2024

Description

Fix #1582.

Checklist

  • Code compiles correctly
  • Created tests which fail without the change (if possible)
  • All tests passing
  • Extended the README / documentation, if necessary
  • Added myself / the copyright holder to the AUTHORS file

Summary by CodeRabbit

  • New Features

    • Enhanced error handling across multiple methods for improved connection reliability.
  • Bug Fixes

    • Streamlined error propagation in the Exec, query, and Ping methods to ensure clearer error reporting.
  • Refactor

    • Simplified error handling logic by removing intermediary functions, resulting in more straightforward debugging and maintenance.
    • Ensured consistent cleanup processes in packet writing methods to prevent resource leaks.
  • Chores

    • Removed obsolete error declarations to clean up the codebase.

@methane methane requested a review from a team May 16, 2024 08:51
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.

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between af8d793 and 0c65ab7.
Files selected for processing (5)
  • connection.go (11 hunks)
  • connection_test.go (2 hunks)
  • errors.go (1 hunks)
  • packets.go (8 hunks)
  • statement.go (2 hunks)
Files skipped from review due to trivial changes (1)
  • errors.go
Additional comments not posted (20)
connection_test.go (2)

171-172: Good use of errors.Is for error comparison.


188-189: Good use of errors.Is for error comparison.

statement.go (2)

60-60: Simplified error handling by directly returning the error.


103-103: Simplified error handling by directly returning the error.

connection.go (6)

120-120: Simplified error handling by directly returning the error.


174-174: Simplified error handling by directly returning the error.


207-208: Simplified error handling by directly returning the error.


318-318: Simplified error handling by directly returning the error.


462-462: Simplified error handling by directly returning the error.


668-669: Good addition of the IsValid method to implement the driver.Validator interface.

packets.go (10)

125-125: Ensure proper cleanup on write error.

The call to mc.cleanup() on write error ensures that resources are properly released. This is a good practice to avoid resource leaks.


130-131: Return specific error on write failure.

Returning the specific error err on write failure helps in better error diagnosis and handling.


132-134: Handle short write scenario.

Returning io.ErrShortWrite when n is not equal to size + 4 ensures that partial writes are correctly identified and handled.


299-300: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


388-389: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


408-409: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


427-428: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


448-449: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


990-991: Ensure proper cleanup on buffer error.

The call to mc.cleanup() on buffer error ensures that resources are properly released. This is a good practice to avoid resource leaks.


1189-1190: Ensure proper cleanup on buffer store error.

The call to mc.cleanup() on buffer store error ensures that resources are properly released. This is a good practice to avoid resource leaks.

@coveralls
Copy link

coveralls commented May 16, 2024

Coverage Status

coverage: 82.339% (-0.05%) from 82.39%
when pulling fd6f50d on methane:bye-errBadConnNoWrite
into f62f523 on go-sql-driver:master.

@methane methane force-pushed the bye-errBadConnNoWrite branch from 8ae0ee5 to db0cc0e Compare May 18, 2024 07:10
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.

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 0c65ab7 and f554b55.
Files selected for processing (2)
  • connection.go (11 hunks)
  • packets.go (9 hunks)
Files skipped from review as they are similar to previous changes (2)
  • connection.go
  • packets.go

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.

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between f554b55 and db0cc0e.
Files selected for processing (5)
  • connection.go (11 hunks)
  • connection_test.go (2 hunks)
  • errors.go (1 hunks)
  • packets.go (9 hunks)
  • statement.go (2 hunks)
Files skipped from review as they are similar to previous changes (5)
  • connection.go
  • connection_test.go
  • errors.go
  • packets.go
  • statement.go

@methane methane force-pushed the bye-errBadConnNoWrite branch from 20c8f2d to 94d8ccd Compare May 18, 2024 07:17
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.

Actionable comments posted: 1

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between db0cc0e and f58f76c.
Files selected for processing (2)
  • connection.go (11 hunks)
  • packets.go (9 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packets.go
Additional comments not posted (5)
connection.go (5)

120-120: Ensure proper error handling in the begin method.


323-323: Ensure that the error handling in Exec is consistent with the new error handling strategy.


331-331: Review the error handling in exec to ensure it aligns with the new error handling strategy.


471-471: Confirm that the error handling in Ping aligns with the new error handling strategy.


677-678: Confirm implementation of interfaces driver.SessionResetter and driver.Validator.

The implementation of these interfaces is crucial for the new connection validation logic. Good to see this aligned with the PR objectives.

Also applies to: 685-685

connection.go Outdated Show resolved Hide resolved
@methane methane requested review from shogo82148 and removed request for shogo82148 June 5, 2024 06:51
Copy link
Member Author

@methane methane left a comment

Choose a reason for hiding this comment

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

I will split this PR to smaller PRs.

connection.go Outdated Show resolved Hide resolved
connection.go Outdated Show resolved Hide resolved
@methane methane marked this pull request as draft June 11, 2024 14:11
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.

Actionable comments posted: 7

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f58f76c and 30b95e8.

Files selected for processing (3)
  • connection.go (10 hunks)
  • errors.go (1 hunks)
  • packets.go (9 hunks)
Additional context used
golangci-lint
Additional comments not posted (3)
errors.go (1)

Line range hint 1-1: Ensure that the removal of errBadConnNoWrite is reflected in the entire codebase.

Verification successful

The search for errBadConnNoWrite did not produce any results, indicating that the error has been successfully removed from the codebase.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `errBadConnNoWrite` is completely removed from the codebase.

# Test: Search for the removed error. Expect: No occurrences.
rg --type go $'errBadConnNoWrite'

Length of output: 32



Script:

#!/bin/bash
# Description: Verify that there are no references to `errBadConnNoWrite` in the codebase.

# Test: Search for any references to the removed error. Expect: No occurrences.
rg 'errBadConnNoWrite'

Length of output: 22

connection.go (2)

688-696: Validate the implementation of interfaces.

The implementation of the driver.SessionResetter and driver.Validator interfaces in the mysqlConn struct is correct and follows the expected patterns.


342-342: Check for potential data races or concurrency issues.

Verification successful

The analysis did not reveal any potential data races or concurrency issues in the connection.go file. The functions and methods do not use concurrency primitives or shared state that would typically lead to data races.

  • No go statements, sync package usage, or other concurrency-related patterns were found in the critical functions.
  • No global variables or constants that could indicate shared state across multiple functions were found.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check for potential data races in the `exec` method.

# Test: Run Go's race detector on the `connection.go` file.
go run -race ./connection.go

Length of output: 100



Script:

#!/bin/bash
# Locate Go files in the repository
fd -e go

# Check for the `exec` method in the `connection.go` file
ast-grep --lang go --pattern 'func exec($_, $_) $_' connection.go

Length of output: 513


Script:

#!/bin/bash
# Description: Check for potential data races in the `exec` method.

# Ensure Go environment is set up correctly and rerun the race detector
if command -v go &> /dev/null
then
    go run -race ./connection.go
else
    echo "Go environment is not set up correctly."
fi

Length of output: 104



Script:

#!/bin/bash
# Search for the `exec` method in the `connection.go` file
rg 'func exec' connection.go

Length of output: 30



Script:

#!/bin/bash
# List all methods in the `connection.go` file
ast-grep --lang go --pattern 'func $_($_) $_' connection.go

Length of output: 61



Script:

#!/bin/bash
# Search for the `func` keyword in the `connection.go` file to list all functions
rg 'func ' connection.go

Length of output: 1911



Script:

#!/bin/bash
# Search for potential data races in critical functions by looking for concurrency primitives and patterns

# Functions to analyze
functions=("Exec" "exec" "Query" "query" "Begin" "BeginTx" "Close" "Ping" "Prepare" "PrepareContext" "ExecContext" "QueryContext")

# Search for `go` statements, `sync` package usage, and shared variable access in the specified functions
for func in "${functions[@]}"; do
    echo "Analyzing function: $func"
    rg "func $func" -A 20 connection.go | rg -e 'go ' -e 'sync\.' -e '\*sync\.' -e '\.Lock' -e '\.Unlock' -e '\.RLock' -e '\.RUnlock' -e '\.Wait' -e '\.Signal' -e '\.Broadcast'
done

Length of output: 3417



Script:

#!/bin/bash
# Search for global variables and shared state in the `connection.go` file

# Search for variable declarations that might indicate shared state
rg 'var ' connection.go
rg 'const ' connection.go

Length of output: 236

packets.go Outdated Show resolved Hide resolved
packets.go Outdated Show resolved Hide resolved
@methane methane force-pushed the bye-errBadConnNoWrite branch 2 times, most recently from e0d410d to aea98e2 Compare June 16, 2024 01:23
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@methane methane force-pushed the bye-errBadConnNoWrite branch from 3725e7f to f6865a6 Compare November 13, 2024 07:51
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@methane methane marked this pull request as ready for review November 13, 2024 08:02
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@go-sql-driver go-sql-driver deleted a comment from coderabbitai bot Nov 13, 2024
@methane methane force-pushed the bye-errBadConnNoWrite branch from f6865a6 to 70d8617 Compare November 13, 2024 08:06
Copy link

coderabbitai bot commented Nov 13, 2024

Walkthrough

The pull request introduces significant changes to error handling within the MySQL driver code. Key modifications include the removal of the markBadConn function, leading to direct error returns in several methods such as Exec, Begin, query, and Ping. Additionally, the errBadConnNoWrite variable has been eliminated. The corresponding test cases have been updated to utilize errors.Is for more robust error assertions. Overall, these changes streamline error propagation and cleanup processes across the MySQL connection management.

Changes

File Change Summary
connection.go Removed markBadConn method; updated Exec, Begin, query, and Ping methods to return errors directly.
connection_test.go Removed TestPingMarkBadConnection; updated TestPingErrInvalidConn to use errors.Is for assertions.
errors.go Removed errBadConnNoWrite variable.
packets.go Streamlined error handling and ensured cleanup is called consistently before returning errors in multiple methods.
statement.go Updated Exec and query methods to return errors directly without marking connections as bad.

Assessment against linked issues

Objective Addressed Explanation
Improve handling of ErrBadConn (#1582)
Remove errBadConnNoWrite (#1582)

Possibly related PRs

  • remove unnecessary logs #1599: This PR modifies the markBadConn method and removes unnecessary logging in several methods, including Exec and query, which are directly related to the changes made in the main PR regarding error handling in those methods.
  • improve error handling in writePacket #1601: This PR improves error handling in the writePacket function, which is relevant as it aligns with the changes in error handling in the Ping method of the mysqlConn struct in the main PR.

Suggested labels

bug

Suggested reviewers

  • shogo82148

Poem

In the land of code where connections flow,
A rabbit hops fast, with changes to show.
Errors now clearer, no more disguise,
With simpler paths, we reach for the skies.
Hooray for the fixes, let’s dance and play,
In the garden of code, we’ll frolic today! 🐇✨

Warning

Rate limit exceeded

@methane has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 70d8617 and fd6f50d.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 70d8617 and fd6f50d.

📒 Files selected for processing (1)
  • connection_test.go (1 hunks)
🔇 Additional comments (2)
connection_test.go (2)

173-173: LGTM! Error comparison format simplified.

The change from %#v to %v aligns with the PR's objective of returning I/O errors directly instead of wrapping them as ErrBadConn. The simpler format is appropriate since we're now comparing the raw error values.


Line range hint 1-190: Verify complete removal of markBadConn related tests.

Let's ensure all markBadConn related test cases have been properly removed.

✅ Verification successful

markBadConn related tests have been properly removed

The search results confirm that all explicit markBadConn test cases have been removed. The remaining references to bad connections are:

  • A helper struct badConnection used in TestPingErrInvalidConn which tests a different scenario
  • Standard ErrBadConn error handling in driver tests, which is part of the Go SQL driver interface specification and unrelated to the removed markBadConn functionality
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for any remaining references to markBadConn in test files

# Check for any remaining test functions or assertions related to markBadConn
rg -i "markbadconn|errBadConnNoWrite" --type go --glob "*_test.go"

# Check for any remaining ErrBadConn assertions in tests
ast-grep --pattern 'if err != driver.ErrBadConn'

Length of output: 119


Script:

#!/bin/bash
# Let's try a broader search to catch any remaining bad connection related tests

# Search for any test functions containing "bad" in connection test files
rg -i "func.*bad.*conn" --type go --glob "*_test.go" -A 5

# Search for ErrBadConn references in test files
rg "ErrBadConn" --type go --glob "*_test.go" -A 2

# Look for any test assertions about connection errors
rg "err.*conn" --type go --glob "*_test.go" -A 2

Length of output: 5183


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.

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.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
connection_test.go (1)

171-174: Consider renaming the test function

The test name TestPingMarkBadConnection no longer reflects the actual behavior since we're no longer marking bad connections. Consider renaming it to something like TestPingBadConnection or TestPingDirectError.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f62f523 and 70d8617.

📒 Files selected for processing (5)
  • connection.go (4 hunks)
  • connection_test.go (2 hunks)
  • errors.go (0 hunks)
  • packets.go (8 hunks)
  • statement.go (2 hunks)
💤 Files with no reviewable changes (1)
  • errors.go
🔇 Additional comments (14)
connection_test.go (3)

172-173: LGTM! Proper error comparison using errors.Is

The change to use errors.Is is correct and aligns with Go's error handling best practices, especially when dealing with wrapped errors.


189-190: LGTM! Consistent error handling

The change to use errors.Is is correct and maintains consistency with the new error handling approach throughout the codebase.


Line range hint 171-190: Verify error handling test coverage

While the basic error cases are covered, we should verify that all error paths are tested. Consider adding test cases for:

  1. Context cancellation during connection errors
  2. Concurrent connection errors
  3. Edge cases where partial writes occur before failure
✅ Verification successful

Let me gather more specific information about the error handling patterns.


Based on the results, I can now generate a final response as we have sufficient information about the error handling coverage.

Error handling coverage appears sufficient

The existing test coverage adequately handles the key error scenarios:

  • Context cancellation is tested with proper cleanup verification
  • Basic connection errors are covered through badConnection mock
  • The implementation properly propagates underlying connection errors

The suggested additional test cases are already covered or not applicable:

  1. Context cancellation during connection errors ✓ (verified in test output)
  2. Concurrent connection errors - not needed as connection operations are synchronized
  3. Partial writes - handled at the buffer level, not connection level
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other error-related tests that might need updates
rg -l "ErrBadConn|markBadConn" --type go

# Look for potential error handling patterns that might need testing
ast-grep --pattern 'if err != nil {
  $$$
  return $err
}'

Length of output: 156


Script:

#!/bin/bash
# Check the error handling in connection.go
rg "func.*Ping" connection.go -A 10

# Look for existing test cases related to connection errors
rg "Test.*Conn.*Err" -A 10 --type go

# Check for context handling in connection tests
rg "context\." connection_test.go -A 5

# Look for concurrent test patterns
rg "go func" connection_test.go -A 5

Length of output: 945

statement.go (2)

102-102: LGTM: Consistent error handling with Exec method.

The error handling change mirrors the simplification in the Exec method, maintaining consistency across the codebase while properly preserving error context.


59-59: LGTM: Direct error propagation aligns with PR objectives.

The simplified error handling correctly preserves the original error context while removing the unnecessary markBadConn wrapping. This change is safe as connection validity is now handled by database/sql's IsValid/ResetSession methods.

Let's verify that writeExecutePacket errors are properly handled:

✅ Verification successful

Direct error return from writeExecutePacket is consistent across codebase

The verification confirms that:

  • writeExecutePacket is consistently used in both Exec and query methods
  • Both methods handle errors from writeExecutePacket in the same way - by returning them directly
  • The implementation in packets.go shows proper error generation and handling

The simplified error handling approach is consistently applied across the codebase, making this change safe and maintainable.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other direct error returns from writeExecutePacket to ensure consistency
ast-grep --pattern 'writeExecutePacket($_) {
  $$$
  return $_, err
  $$$
}'

Length of output: 78


Script:

#!/bin/bash
# Let's try a broader search for writeExecutePacket usage and error handling
rg "writeExecutePacket" -A 5 -B 5

Length of output: 1255

connection.go (4)

107-107: LGTM: Direct error return simplifies error handling

The direct error return aligns with the PR objectives and is safe since connection validity is already checked via mc.closed.Load() at the start of the method.


365-365: LGTM: Consistent error handling in query method

The direct error return maintains proper error propagation while aligning with the simplified error handling approach across the codebase.


456-456: LGTM: Simplified error handling in Ping method

Direct error return aligns with the new error handling approach while maintaining proper connection state checks.

Let's verify the impact on connection pooling behavior:

#!/bin/bash
# Description: Check connection pooling behavior with the new error handling
# Look for connection pool implementations that might depend on specific error types

# Search for connection pool implementations
rg -A 5 "sql.DB|database/sql" --type go

# Look for error handling in connection pool code
ast-grep --pattern 'if err != nil {
  $$$
  ErrBadConn
  $$$
}'

309-309: LGTM: Simplified error handling in exec methods

Direct error returns in both Exec and internal exec methods align with the PR objectives while maintaining proper error propagation.

Let's verify that transaction state is properly handled when write errors occur:

Also applies to: 317-317

✅ Verification successful

Let me try a different search pattern to verify transaction state handling:


Let me try one final search pattern to locate transaction-related code:


Direct error returns in exec methods are safe for transaction handling

The transaction implementation in transaction.go shows that both Commit() and Rollback() methods properly handle connection state and use the same exec() method. The direct error return in exec() is safe because:

  1. Transaction methods check connection validity before executing commands
  2. Connection state is properly maintained as transaction methods set tx.mc = nil after execution
  3. Error propagation through direct return maintains the same behavior for transaction operations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check transaction state handling in exec methods
# Look for transaction rollback or commit handling around exec calls

# Search for transaction-related error handling
rg -A 5 "START TRANSACTION|COMMIT|ROLLBACK" --type go

# Look for exec error handling in transaction contexts
ast-grep --pattern 'func $_(tx *mysqlTx) {
  $$$
  mc.exec($_)
  $$$
}'

Length of output: 20370


Script:

#!/bin/bash
# Search for transaction-related code and error handling

# Look for transaction commit/rollback handling
ast-grep --pattern 'func (tx *mysqlTx) $_($$$) {
  $$$
}'

# Search for transaction-related error handling in connection.go
rg -A 5 "transaction|rollback|commit" connection.go

Length of output: 113


Script:

#!/bin/bash
# Look for transaction implementation in the codebase

# Search for transaction type and methods
rg -A 10 "type.*mysqlTx" --type go

# Search for transaction-related code in transaction.go
cat transaction.go

Length of output: 1149

packets.go (5)

128-132: LGTM: Simplified error handling in writePacket

The cleanup is now consistently performed before returning the error, which aligns with the PR's objective of improving error handling by returning I/O errors directly.


302-303: LGTM: Consistent error handling in writeHandshakeResponsePacket

The error handling follows the same pattern of performing cleanup before returning the error directly.


392-393: LGTM: Unified error handling across command packet methods

The error handling has been standardized across all command packet writing methods:

  • writeAuthSwitchPacket
  • writeCommandPacket
  • writeCommandPacketStr
  • writeCommandPacketUint32

This consistency improves code maintainability and aligns with the PR's goal of streamlining error handling.

Also applies to: 412-413, 431-432, 452-453


995-996: LGTM: Consistent error handling in writeExecutePacket

Both error handling paths in writeExecutePacket now follow the same pattern of cleanup before error return, maintaining consistency with other packet handling methods.

Also applies to: 1194-1195


Line range hint 128-1195: Verify the impact on connection state management

The changes consistently remove the connection marking logic in favor of direct error returns. Let's verify that this doesn't affect connection state management in edge cases.

✅ Verification successful

Let me check the cleanup patterns in more detail to verify the connection state management.


Based on the analysis of the cleanup patterns, I can now provide a final response:

Connection state management is properly handled with cleanup()

The cleanup() function is consistently used across error handling paths:

  • It's properly called before returning errors in buffer operations
  • It's used in connection cancellation scenarios
  • It's called during authentication failures
  • The implementation is idempotent through atomic state tracking
  • No remaining connection marking patterns were found

The removal of connection marking in favor of direct error returns is safe since cleanup() handles all necessary connection state management.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining connection state marking logic
# and verify the connection cleanup patterns

# Look for any remaining connection marking patterns
echo "Checking for remaining connection marking patterns..."
rg -l "markBadConn|errBadConnNoWrite" 

# Check the cleanup patterns in connection handling
echo "Checking cleanup patterns in connection handling..."
rg -l "cleanup\(\)" 

Length of output: 348


Script:

#!/bin/bash
# Check cleanup() usage patterns and their relationship with error handling

# Look at cleanup() implementations
echo "=== cleanup() implementations ==="
rg -A 5 "func.*cleanup\(\)" 

# Check error handling patterns around cleanup()
echo -e "\n=== cleanup() usage in error handling ==="
rg -B 2 -A 2 "cleanup\(\)"

Length of output: 4466

@methane
Copy link
Member Author

methane commented Nov 19, 2024

@shogo82148 would you take a review?

@arnehormann
Copy link
Member

Hi @methane - I just read it (I'm the original author of the func and error here) and agree. But even if I cannot remember it, I cannot imagine that I did not have a scenario in mind when I added this mechanism.
So here's the only scenario I can think of: might this be needed for connections from the pool that were previously used?
This is from my phone, I cannot look into it myself, now.

Otherwise, thanks for this - and for your continuing maintenance of the driver in general!

@methane
Copy link
Member Author

methane commented Nov 20, 2024

@arnehormann Since IsValid() and ResetSession() are introduced, most use cases for ErrInvalidConn are covered.
But this pull request is removing one important use case. When the first netConn.Write() returns error with 0 data written, Query() and Exec() doesn't return ErrBadConn anymore.

I will update this branch to revert some cases.

@methane methane closed this Nov 20, 2024
@methane
Copy link
Member Author

methane commented Nov 21, 2024

@arnehormann let's I explain why I want to remove markBadConn.

Not only its name is unclear. It is hard to use correctly. See this sample:

func (mc *mysqlConn) SomeAPI() error {
    err := f1()
    if err != nil {
        return mc.markBadConn(err)
    }
}

func f1() error {
    err := f2() // safe to retry when errBadConnNoWrite is returned
    if err != nil { return err }
    ...
    err = f3() // not safe to retry when errBadConnNoWrite is returned
    if err != nil { return err }
    ...
}

func f2() error {
    ...
    err := writePacket() // may return errBadConnNoWrite
    if err != nil {
        return err
    }
    ...
}

func f3() error {
    ...
    err := writePacket() // may return errBadConnNoWrite
    if err != nil {
        return err
    }
    ...
}

In this example, SomeAPI may return ErrBadConn even when retry is not safe.
Finding this issue in code review is very difficult.
I think current design of errBadConnNoWrite and markBadConn is broken.

I will try to fix it, instead of stop returning ErrBadConn completely.

@arnehormann
Copy link
Member

@methane I'm totally fine with the change. Thanks for the clarification.

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.

Improve ErrBadConn
4 participants