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

[bug] proxy: session does not transfer after COM_STMT_CLOSE. #18613

Merged
merged 1 commit into from
Sep 7, 2024

Conversation

volgariver6
Copy link
Contributor

@volgariver6 volgariver6 commented Sep 7, 2024

User description

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue https://github.com/matrixorigin/MO-Cloud/issues/4022

What this PR does / why we need it:

there is no response from server after client send a COM_STMT_CLOSE cmd,
which will cause the session cannot be transferred forever. So ignore the
send time when client send a COM_STMT_CLOSE cmd.


PR Type

Bug fix, Tests


Description

  • Fixed a bug where sessions did not transfer after a COM_STMT_CLOSE command by ignoring the send time for such commands.
  • Introduced a buffer variable tempBuf to improve buffer handling.
  • Added utility functions isEmptyPacket and isDeallocatePacket to identify packet types.
  • Updated logic to conditionally set lastCmdTime based on packet type.
  • Added unit tests for the new utility functions to ensure correct packet type identification.

Changes walkthrough 📝

Relevant files
Bug fix
tunnel.go
Improve session handling and command time management         

pkg/proxy/tunnel.go

  • Introduced tempBuf to hold buffer data for processing.
  • Added checks for empty and deallocate packets.
  • Updated logic to set lastCmdTime conditionally.
  • +14/-7   
    Enhancement
    util.go
    Add utility functions for packet type checking                     

    pkg/proxy/util.go

  • Added isEmptyPacket function to check for empty packets.
  • Added isDeallocatePacket function to identify deallocate packets.
  • +15/-0   
    Tests
    util_test.go
    Add tests for packet utility functions                                     

    pkg/proxy/util_test.go

  • Added tests for isDeallocatePacket function.
  • Added tests for isEmptyPacket function.
  • +27/-0   

    💡 PR-Agent usage:
    Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    Copy link

    qodo-merge-pro bot commented Sep 7, 2024

    PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

    PR Reviewer Guide 🔍

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Key issues to review

    Potential Race Condition
    The p.mu.lastCmdTime is being set without acquiring a lock, which could lead to a race condition if multiple goroutines access this field concurrently.

    Error Handling
    The function isEmptyPacket is called twice in the conditional statement. This could be optimized to improve readability and performance.

    @mergify mergify bot requested a review from sukki37 September 7, 2024 04:25
    @mergify mergify bot added the kind/bug Something isn't working label Sep 7, 2024
    Copy link

    qodo-merge-pro bot commented Sep 7, 2024

    PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Maintainability
    Extract pipe handling logic into separate functions

    Consider extracting the logic for handling the server-to-client pipe into a separate
    function to improve code readability and maintainability.

    pkg/proxy/tunnel.go [559-597]

     if p.name == pipeServerToClient {
    +  handleServerToClientPipe(p, tempBuf, peer)
    +} else {
    +  handleClientToServerPipe(p, tempBuf)
    +}
    +
    +// ... (define the new functions below)
    +
    +func handleServerToClientPipe(p *pipe, tempBuf []byte, peer *pipe) {
       var currSeq int16
     
       // issue#16042
       if len(tempBuf) > 3 {
         currSeq = int16(tempBuf[3])
       }
     
    -  // last sequence id is 255 and current sequence id is 0, the
    -  // sequence ID is rotated, in which case, we do NOT allow to
    -  ...
    -  if !p.mu.inTxn && p.tun.transferIntent.Load() && !rotated {
    -    peer.wg.Add(1)
    -    p.transferred = true
    -  }
    -  if len(tempBuf) > 3 {
    -    lastSeq = int16(tempBuf[3])
    -  }
    -  p.mu.lastCmdTime = time.Now()
    -} else {
    +  // ... (rest of the server-to-client logic)
    +}
    +
    +func handleClientToServerPipe(p *pipe, tempBuf []byte) {
       if isEmptyPacket(tempBuf) {
         p.logger.Warn("there comes an empty packet from client")
       }
       if !isEmptyPacket(tempBuf) && !isDeallocatePacket(tempBuf) {
         p.mu.lastCmdTime = time.Now()
       }
     }
     
    Suggestion importance[1-10]: 8

    Why: Extracting the logic into separate functions significantly improves code readability and maintainability by organizing the code into smaller, more manageable pieces.

    8
    Best practice
    Move variable declaration closer to its first usage

    Consider moving the tempBuf declaration closer to where it's first used to improve
    code readability and reduce the scope of the variable.

    pkg/proxy/tunnel.go [556-564]

    -tempBuf := p.src.readAvailBuf()
     // set txn status and cmd time within the mutex together.
     // only server->client pipe need to set the txn status.
     if p.name == pipeServerToClient {
       var currSeq int16
    +  tempBuf := p.src.readAvailBuf()
     
       // issue#16042
       if len(tempBuf) > 3 {
         currSeq = int16(tempBuf[3])
       }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Moving the tempBuf declaration closer to its first use can improve readability and reduce the variable's scope, which is a good practice for maintainability, but it is not crucial.

    7
    Enhancement
    Simplify function by combining conditions into a single return statement

    The isEmptyPacket function can be simplified to a single return statement, making it
    more concise and easier to read.

    pkg/proxy/util.go [101-106]

     func isEmptyPacket(p []byte) bool {
    -  if p == nil || len(p) == 0 {
    -    return true
    -  }
    -  return false
    +  return p == nil || len(p) == 0
     }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Simplifying the function to a single return statement makes the code more concise and easier to read, which is a minor but beneficial enhancement.

    7
    Improve function documentation with more detailed explanation

    The comment for isDeallocatePacket function is incomplete. Consider providing a more
    descriptive comment explaining what a MySQL deallocate packet is and how it's
    identified.

    pkg/proxy/util.go [108-114]

    -// isDeallocatePacket returns true if []byte is a MySQL
    +// isDeallocatePacket returns true if the given byte slice represents a MySQL
    +// COM_STMT_CLOSE packet, which is used to deallocate a prepared statement.
    +// The packet is identified by having a length of at least 5 bytes and
    +// the 5th byte (index 4) being 0x19 (25 in decimal).
     func isDeallocatePacket(p []byte) bool {
       if len(p) > 4 && p[4] == 0x19 {
         return true
       }
       return false
     }
     
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    Why: Improving the documentation with a more detailed explanation enhances code clarity and helps future developers understand the function's purpose, though it is not critical.

    6

    @matrix-meow matrix-meow added the size/S Denotes a PR that changes [10,99] lines label Sep 7, 2024
    @mergify mergify bot merged commit f110eaf into matrixorigin:1.2-dev Sep 7, 2024
    18 checks passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    Bug fix kind/bug Something isn't working Review effort [1-5]: 3 size/S Denotes a PR that changes [10,99] lines Tests
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    4 participants