chengxilo opened a new pull request, #1916:
URL: https://github.com/apache/iggy/pull/1916

   # Some explanation
   ## What I did
   1. refactor logic for building new Go SDK client using builder pattern
   2. I changed some function to make them align with Rust SDK ( not only their 
name, I also edited part of their output)
   3. I updated the tests.
   
   ## Why we need to refactor it.
   ( I copied the message I sent in discord a few days ago here)
   Since currently, the golang sdk is very out dated and when we create a 
client the 
   in rust when we create client:
   ```rust
   let client = IggyClientBuilder::new()
           .with_tcp()
           .with_server_address(get_tcp_server_addr())
           .build()?;
   ```
   While in golang we create client:
   ```go
   factory := iggy.IggyClientFactory{}
   msgStream, _ := factory.CreateMessageStream(iggcon.IggyConfiguration{
       BaseAddress: "vm:8090",
       Protocol:    "tcp",
   })
   ```
   Since the Rust SDK is considered the primary or canonical implementation, it 
makes sense for other language SDKs to follow its design principles closely — 
including using the same repository name and similar function names. Clearly, 
the current Go SDK does not meet this requirement: its function names don’t 
clearly describe their purpose, and the overall design pattern feels less 
elegant.
   
   ## My solution
   So what I did is to read the rust sdk source code and ... almost directly 
ported its logic to Go.  I want to explain why I decided not to use the option 
pattern discussed earlier with @haze518, even though the option pattern is 
commonly considered best practice in Go.  At first, I choose to follow the 
example of https://github.com/nats-io/nats.go/blob/main/nats.go#L867 . It's 
elegent, but it would not work so well in our use case, since we need to 
support tcp/http/quic.
   
   It's because three different protocol have three different client. 
   Here is a simplified example showing the potential issue:
   ```
   package main
   
   type Options struct {
        protocol string
        aTcpOpt bool // a TCP-specific option
        aHttpOpt bool // a HTTP-specific option
   }
   type Option func(*Options)
   
   func WithTcp(opts *Options) {
        opts.protocol = "tcp"
   }
   func WithHttp(opts *Options) {
        opts.protocol = "http"
   }
   func WithATcpOpt(opts *Options) {
        opts.aTcpOpt = true
   }
   func WithAHttpOpt(opts *Options) {
        opts.aHttpOpt = true
   }
   func New(opts ...Option) {
        options := &Options{
                protocol: "tcp",
                aTcpOpt:  false,
                aHttpOpt: false,
        }
        for _, opt := range opts {
                opt(options)
        }
        // ... build the client with option
   }
   
   func main() {
        New(WithTcp, WithAHttpOpt, WithATcpOpt) // user may add a http option 
when they are using tcp
   }
   ```
   So, I think it is not a good choice as I don't know how to solve this 
problem while using option pattern. But if we use builder pattern, it allows us 
to control and constrain users’ choices more effectively, preventing invalid 
combinations and leading to a cleaner, safer API.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to