Skip to content

Commit

Permalink
Merge pull request #376 from shushenghong/main
Browse files Browse the repository at this point in the history
feat: support multiple addresses #317
  • Loading branch information
rueian authored Sep 23, 2023
2 parents ebb261d + 5392a65 commit d734aa1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 16 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,17 @@ You can use `ParseURL` or `MustParseURL` to construct a `ClientOption`:

```go
// connect to a redis cluster
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:7001"))
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:7001?addr=127.0.0.1:7002&addr=127.0.0.1:7003"))
// connect to a redis node
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:6379"))
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:6379/0"))
// connect to a redis sentinel
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:26379?master_set=my_master"))
client, err = rueidis.NewClient(rueidis.MustParseURL("redis://127.0.0.1:26379/0?master_set=my_master"))
```

The url must be started with either `redis://`, `rediss://` or `unix://`.

Currently supported parameters `dial_timeout`, `write_timeout`, `protocol`, `client_cache`, `client_name`, `max_retries`

## Arbitrary Command

If you want to construct commands that are absent from the command builder, you can use `client.B().Arbitrary()`:
Expand Down
36 changes: 23 additions & 13 deletions url.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,24 @@ import (
// https://github.com/redis/redis-specifications/blob/master/uri/redis.txt
// Example:
//
// redis://<user>:<password>@<host>:<port>/<db_number>
// unix://<user>:<password>@</path/to/redis.sock>?db=<db_number>
// redis://<user>:<password>@<host>:<port>/<db_number>
// redis://<user>:<password>@<host>:<port>?addr=<host2>:<port2>&addr=<host3>:<port3>
// unix://<user>:<password>@</path/to/redis.sock>?db=<db_number>
func ParseURL(str string) (opt ClientOption, err error) {
u, _ := url.Parse(str)
parseAddr := func(hostport string) (host string, addr string) {
host, port, _ := net.SplitHostPort(hostport)
if host == "" {
host = u.Host
}
if host == "" {
host = "localhost"
}
if port == "" {
port = "6379"
}
return host, net.JoinHostPort(host, port)
}
switch u.Scheme {
case "unix":
opt.DialFn = func(s string, dialer *net.Dialer, config *tls.Config) (conn net.Conn, err error) {
Expand All @@ -33,17 +47,8 @@ func ParseURL(str string) (opt ClientOption, err error) {
return opt, fmt.Errorf("redis: invalid URL scheme: %s", u.Scheme)
}
if opt.InitAddress == nil {
host, port, _ := net.SplitHostPort(u.Host)
if host == "" {
host = u.Host
}
if host == "" {
host = "localhost"
}
if port == "" {
port = "6379"
}
opt.InitAddress = []string{net.JoinHostPort(host, port)}
host, addr := parseAddr(u.Host)
opt.InitAddress = []string{addr}
if opt.TLSConfig != nil {
opt.TLSConfig.ServerName = host
}
Expand Down Expand Up @@ -75,7 +80,12 @@ func ParseURL(str string) (opt ClientOption, err error) {
return opt, fmt.Errorf("redis: invalid write timeout: %q", q.Get("write_timeout"))
}
}
for _, addr := range q["addr"] {
_, addr = parseAddr(addr)
opt.InitAddress = append(opt.InitAddress, addr)
}
opt.AlwaysRESP2 = q.Get("protocol") == "2"
opt.DisableCache = q.Get("client_cache") == "0"
opt.DisableRetry = q.Get("max_retries") == "0"
opt.ClientName = q.Get("client_name")
opt.Sentinel.MasterSet = q.Get("master_set")
Expand Down
6 changes: 6 additions & 0 deletions url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func TestParseURL(t *testing.T) {
if opt, err := ParseURL("redis://localhost"); err != nil || opt.InitAddress[0] != "localhost:6379" {
t.Fatalf("unexpected %v %v", opt, err)
}
if opt, err := ParseURL("redis://?addr=:6380&addr=:6381"); err != nil || opt.InitAddress[0] != "localhost:6379" || opt.InitAddress[1] != "localhost:6380" || opt.InitAddress[2] != "localhost:6381" {
t.Fatalf("unexpected %v %v", opt, err)
}
if opt, err := ParseURL("redis://myhost:1234"); err != nil || opt.InitAddress[0] != "myhost:1234" {
t.Fatalf("unexpected %v %v", opt, err)
}
Expand Down Expand Up @@ -48,6 +51,9 @@ func TestParseURL(t *testing.T) {
if opt, err := ParseURL("redis://?protocol=2"); !opt.AlwaysRESP2 {
t.Fatalf("unexpected %v %v", opt, err)
}
if opt, err := ParseURL("redis://?client_cache=0"); !opt.DisableCache {
t.Fatalf("unexpected %v %v", opt, err)
}
if opt, err := ParseURL("redis://?max_retries=0"); !opt.DisableRetry {
t.Fatalf("unexpected %v %v", opt, err)
}
Expand Down

0 comments on commit d734aa1

Please sign in to comment.