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

Specify a custom dial function per config #1527

Merged
merged 3 commits into from
Nov 10, 2024

Conversation

aaronjheng
Copy link
Contributor

@aaronjheng aaronjheng commented Dec 15, 2023

Description

Specify a custom dial function per config instead of using RegisterDialContext. It's hard to bind different state infomation for dialing with RegisterDialContext. Like SSH tunneling, if we want to use diffrent SSH connections, unique net for RegisterDialContext is required If I'm not wrong.

Use cases:

  1. SSH tunneling per Config/dsn

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
    • Introduced a configurable network connection handling feature, allowing users to specify custom methods for establishing network connections.
    • Added a new DialFunc field in the Config struct for enhanced control over connection establishment.
  • Bug Fixes
    • Improved error handling during connection attempts, ensuring consistent timeout application across different dialing methods.
  • Documentation
    • Updated Config struct documentation to reflect the addition of the DialFunc field, enabling more controlled connection processes.

Copy link

coderabbitai bot commented Dec 15, 2023

Walkthrough

The recent updates introduce a new field DialFunc to the Config struct in dsn.go, allowing users to specify a custom dial function for network connections. This addition enhances the flexibility of connection handling without altering existing functionality. The overall structure and logic of the Config class remain unchanged, and the new field is well-documented for clarity.

Changes

File(s) Change Summary
dsn.go Introduced a DialFunc field in the Config struct for customizable connection establishment. Documentation added.
connector.go Modified the Connect method to utilize DialFunc for establishing connections, enhancing flexibility in dialing. Error handling and context management improved.

🐇 In the meadow, connections bloom,
With DialFunc, we chase the gloom.
A flexible path, both near and far,
Our network hops, like a shooting star!
🐇✨

Possibly related PRs

  • allow unknown collation name #1604: The changes in dsn.go regarding the addition of the charsets field and modifications to the FormatDSN and parseDSNParams functions are related to the changes in the same file in this PR, which also involves updates to the Config struct and its handling of connection parameters.

Suggested reviewers

  • shogo82148

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b52c4c5 and 2d6a857.

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

90-95: Refactored context creation enhances maintainability

The timeout context dctx is now initialized before the conditional blocks, eliminating duplicated code and ensuring consistent timeout handling across all connection methods.


97-109: Custom DialFunc integration is correctly implemented

The code correctly uses the user-defined DialFunc from the configuration when it is not nil. If DialFunc is not provided, it appropriately falls back to the registered dialers or the default net.Dialer. The context dctx is consistently passed, ensuring that any configured timeouts are respected. Error handling remains consistent across all branches.


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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0004702 and df2bedf.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (1 hunks)
Additional comments: 6
connector.go (3)
  • 80-92: Please ensure to add tests that cover the new functionality introduced by the use of c.cfg.DialFunc. This is crucial for verifying that the custom dial function works as expected and handles errors properly.

  • 80-92: Remember to update the documentation to include information about the new DialFunc configuration option. This will help users understand how to use the new feature.

  • 80-92: If this is your first contribution to the project, please add yourself to the AUTHORS file as per the project's contribution guidelines.

dsn.go (3)
  • 55-55: Verify whether the DialFunc field should be included in the FormatDSN method output. If it is intended to be part of the DSN string, appropriate handling needs to be added.

  • 55-55: Confirm that the DialFunc field does not need to be normalized within the normalize method. If it does require normalization, appropriate logic should be added.

  • 55-55: Ensure that the DialFunc field does not need to be parsed from the DSN string in the parseDSNParams function. If it should be included, parsing logic will need to be implemented.

dsn.go Outdated Show resolved Hide resolved
connector.go Outdated
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Addr)
Copy link

Choose a reason for hiding this comment

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

There is a potential issue with error handling after the custom DialFunc is called. If an error occurs, it should be handled similarly to how it's handled after the global dial function or net.Dialer is called.

+		mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Addr)
+		if err != nil {
+			return nil, err
+		}

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
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Addr)
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Addr)
if err != nil {
return nil, err
}

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: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0004702 and ac7765c.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (2 hunks)
Additional comments: 5
connector.go (1)
  • 84-91: The implementation of the conditional dial function usage looks correct. It checks if a custom dial function is provided and uses it to establish a connection. If not, it falls back to the previously existing dialing mechanisms. This change aligns with the PR's objective to allow specifying a custom dial function for each configuration.

However, ensure that the custom DialFunc is thoroughly tested, especially since the PR checklist indicates that tests for this new functionality are pending. It's important to cover various scenarios, including timeouts and error handling, to ensure the new dialing mechanism works as expected.

dsn.go (4)
  • 13-13: The import of the context package is appropriate given the new DialFunc field in the Config struct.

  • 70-71: The addition of the DialFunc field to the Config struct enables per-configuration custom dial functions, which is a key objective of this PR.

  • 70-71: The function signature for DialFunc is correct and follows the conventional pattern for dial functions in Go, taking a context.Context, network type, and address, and returning a net.Conn and an error.

  • 74-74: Verify if any normalization is required for the new DialFunc field within the normalize method.

dsn.go Outdated Show resolved Hide resolved
dsn.go Outdated Show resolved Hide resolved
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 0004702 and 2d38b27.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (3 hunks)
Files skipped from review as they are similar to previous changes (2)
  • connector.go
  • dsn.go

dsn.go Outdated Show resolved Hide resolved
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 0004702 and f0f5dd4.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (2 hunks)
Files skipped from review as they are similar to previous changes (2)
  • connector.go
  • dsn.go

connector.go Show resolved Hide resolved
dsn.go Outdated Show resolved Hide resolved
dsn.go Outdated Show resolved Hide resolved
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 0004702 and 31d874d.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (2 hunks)
Files skipped from review as they are similar to previous changes (2)
  • connector.go
  • dsn.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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 3147497 and 10f45a3.
Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (1 hunks)
Additional comments: 3
connector.go (2)
  • 90-97: The implementation of the custom DialFunc usage within the Connect method is correctly checking if DialFunc is provided and uses it if available. This approach allows for flexibility in establishing network connections, aligning with the PR's objectives. However, consider adding a comment explaining the purpose of the conditional context.WithTimeout creation based on mc.cfg.Timeout to clarify its intent for future maintainers.
  • 99-113: The fallback mechanism to use the default dialing method when DialFunc is not provided is correctly implemented. However, there's a past comment by methane suggesting not to lookup dials when c.cfg.DialFunc != nil. This has been addressed by the conditional check for c.cfg.DialFunc at the beginning of this segment. It's good practice to ensure that unnecessary operations are avoided when a custom dial function is provided, enhancing performance and maintainability.
dsn.go (1)
  • 57-57: The addition of the DialFunc field to the Config struct is correctly implemented, allowing users to specify a custom dial function for connection establishment. This change effectively addresses the PR's objectives by enhancing flexibility in connection handling. It's important to ensure that documentation is updated to include information about this new field and how to use it, as it introduces a significant new capability for users.

connector.go Outdated
Comment on lines 87 to 115
mc.parseTime = mc.cfg.ParseTime

// Connect to Server
dialsLock.RLock()
dial, ok := dials[mc.cfg.Net]
dialsLock.RUnlock()
if ok {
if c.cfg.DialFunc != nil {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
dialsLock.RLock()
dial, ok := dials[mc.cfg.Net]
dialsLock.RUnlock()
if ok {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
}
}

if err != nil {
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 diff hunks, and no overlapping diff hunk was found. Original lines [175-179]

The TLS configuration used in the default and custom dial functions does not specify a minimum version. It's recommended to explicitly set the minimum TLS version to TLS 1.3 to ensure stronger security guarantees. Additionally, the use of InsecureSkipVerify: true in the skip-verify case should be carefully considered, as it disables TLS/SSL certificate verification, making the connection vulnerable to man-in-the-middle (MTM) attacks. This should only be used for debugging purposes and not in production environments.

- cfg.TLS = &tls.Config{InsecureSkipVerify: true}
+ cfg.TLS = &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS13}

And for other relevant TLS configurations, ensure MinVersion: tls.VersionTLS13 is added.

@aaronjheng aaronjheng requested a review from methane June 13, 2024 07:06
@dolmen
Copy link
Contributor

dolmen commented Jun 24, 2024

I would like to see in the description of this PR an example of how that new feature would be used. Because I would to ensure this can't be implemented in another way.

@aaronjheng
Copy link
Contributor Author

I’m not quite sure what kind of example you want. I think my PR description has already explained it clearly. Without using different custom net names, RegisterDialContext can only register the SSH Tunnel globally. However, what I want is to be able to use multiple SSH Tunnels in one program without registering the net globally. In this PR, different Tunnels can be configured through DSN configuration.

@aaronjheng
Copy link
Contributor Author

@methane Sorry to bother. Can we get this merged, or is there anything else I can do?

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

🧹 Outside diff range and nitpick comments (2)
dsn.go (2)

Line range hint 164-217: Consider updating the normalize method

The normalize method is responsible for setting default values and validating the configuration. Consider adding validation or default behavior for the new DialFunc field in this method. This could include checking if a custom DialFunc is provided and setting a default if it's not.

Here's a suggested addition to the normalize method:

func (cfg *Config) normalize() error {
    // ... existing code ...

    // Set default DialFunc if not provided
    if cfg.DialFunc == nil {
        cfg.DialFunc = (&net.Dialer{Timeout: cfg.Timeout}).DialContext
    }

    // ... rest of the method ...
}

This ensures that there's always a valid dial function, defaulting to the standard net.Dialer if a custom one isn't provided.


58-58: Add documentation for DialFunc

Consider adding documentation to explain how to use the new DialFunc field. This could include an example of how to set a custom dial function and any considerations users should keep in mind when using this feature.

You could add a comment like this above the DialFunc field:

// DialFunc allows for a custom dial function to be used for creating
// connections. If not set, the default dialer will be used.
// Example usage:
//
//  cfg := mysql.NewConfig()
//  cfg.DialFunc = func(ctx context.Context, addr string) (net.Conn, error) {
//      return net.Dial("tcp", addr)
//  }
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 10f45a3 and 63f0c4b.

📒 Files selected for processing (2)
  • connector.go (1 hunks)
  • dsn.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (2)
dsn.go (2)

58-58: LGTM: Addition of DialFunc field

The new DialFunc field in the Config struct is a good addition. It allows users to specify a custom dialing function for creating network connections, which aligns with the PR objectives. The type signature is appropriate and matches the standard net.Dialer function.


58-58: Reminder: Update Clone method

Please ensure that the Clone method of the Config struct has been updated to include the new DialFunc field. This is necessary to ensure that any custom dial function is correctly copied when a Config instance is cloned.

To verify if the Clone method has been updated, you can run the following command:

If the Clone method doesn't include the DialFunc field, consider updating it as follows:

func (cfg *Config) Clone() *Config {
    cp := *cfg
    if cp.DialFunc != nil {
        cp.DialFunc = cfg.DialFunc
    }
    // ... existing code ...
    return &cp
}

connector.go Outdated
Comment on lines 90 to 113
if c.cfg.DialFunc != nil {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
dialsLock.RLock()
dial, ok := dials[mc.cfg.Net]
dialsLock.RUnlock()
if ok {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor to eliminate duplicated timeout context creation code

The creation of the timeout context dctx is duplicated in both the if c.cfg.DialFunc != nil block and the if ok block within the else. To enhance maintainability and reduce code duplication, consider initializing dctx before these conditionals so it can be used in all branches.

Here's a suggested refactoring:

+    dctx := ctx
+    if mc.cfg.Timeout > 0 {
+        var cancel context.CancelFunc
+        dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
+        defer cancel()
+    }
     if c.cfg.DialFunc != nil {
-        dctx := ctx
-        if mc.cfg.Timeout > 0 {
-            var cancel context.CancelFunc
-            dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
-            defer cancel()
-        }
         mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
     } else {
         dialsLock.RLock()
         dial, ok := dials[mc.cfg.Net]
         dialsLock.RUnlock()
         if ok {
-            dctx := ctx
-            if mc.cfg.Timeout > 0 {
-                var cancel context.CancelFunc
-                dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
-                defer cancel()
-            }
             mc.netConn, err = dial(dctx, mc.cfg.Addr)
         } else {
             nd := net.Dialer{Timeout: mc.cfg.Timeout}
-            mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
+            mc.netConn, err = nd.DialContext(dctx, mc.cfg.Net, mc.cfg.Addr)
         }
     }
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if c.cfg.DialFunc != nil {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
dialsLock.RLock()
dial, ok := dials[mc.cfg.Net]
dialsLock.RUnlock()
if ok {
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
mc.netConn, err = dial(dctx, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr)
}
dctx := ctx
if mc.cfg.Timeout > 0 {
var cancel context.CancelFunc
dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout)
defer cancel()
}
if c.cfg.DialFunc != nil {
mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr)
} else {
dialsLock.RLock()
dial, ok := dials[mc.cfg.Net]
dialsLock.RUnlock()
if ok {
mc.netConn, err = dial(dctx, mc.cfg.Addr)
} else {
nd := net.Dialer{Timeout: mc.cfg.Timeout}
mc.netConn, err = nd.DialContext(dctx, mc.cfg.Net, mc.cfg.Addr)
}
}

dsn.go Outdated
ReadTimeout time.Duration // I/O read timeout
WriteTimeout time.Duration // I/O write timeout
Logger Logger // Logger
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error) // Specifies the dial function for creating connections
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error) // Specifies the dial function for creating connections
// Specifies the dial function for creating connections
DialFunc func(ctx context.Context, network, addr string) (net.Conn, error)

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)
dsn.go (1)

58-59: Consider enhancing the documentation while maintaining conciseness.

The documentation could benefit from a brief mention of the default behavior when DialFunc is nil.

-	// DialFunc specifies the dial function for creating connections
+	// DialFunc specifies an optional dial function for creating connections.
+	// If nil, the default network dialer is used.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 63f0c4b and b52c4c5.

📒 Files selected for processing (1)
  • dsn.go (1 hunks)
🔇 Additional comments (3)
dsn.go (3)

Line range hint 201-219: LGTM! The Clone method correctly handles DialFunc.

The shallow copy cp := *cfg adequately handles the function pointer DialFunc. No explicit copying is needed.


Line range hint 221-565: LGTM! Correct handling of DialFunc in DSN operations.

The DialFunc field is appropriately excluded from DSN serialization and parsing operations, as it's a runtime configuration that should be set programmatically, similar to TLS and Loc fields.


58-59: Tests needed for the new DialFunc feature.

Please add tests to verify:

  1. Custom dialers work as expected
  2. Nil DialFunc falls back to default behavior
  3. Context cancellation is properly handled

@coveralls
Copy link

Coverage Status

coverage: 82.39% (-0.01%) from 82.403%
when pulling 2d6a857 on aaronjheng:dial-func
into 00dc21a on go-sql-driver:master.

@methane methane merged commit 91ad4fb into go-sql-driver:master Nov 10, 2024
35 of 38 checks passed
@aaronjheng aaronjheng deleted the dial-func branch November 10, 2024 09:44
methane pushed a commit to methane/mysql that referenced this pull request Nov 13, 2024
Specify a custom dial function per config instead of using
RegisterDialContext.
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.

4 participants