Skip to content

Commit 066ae4d

Browse files
authored
Merge branch 'master' into otel
2 parents b9ac847 + 53daf77 commit 066ae4d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1348
-377
lines changed

Diff for: .github/actions/run-tests/action.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ runs:
2525
2626
# Mapping of redis version to redis testing containers
2727
declare -A redis_version_mapping=(
28-
["8.0-M03"]="8.0-M04-pre"
28+
["8.0-M05"]="8.0-M05-pre"
2929
["7.4.2"]="rs-7.4.0-v2"
3030
["7.2.7"]="rs-7.2.0-v14"
3131
)

Diff for: .github/wordlist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Lua
2929
MSSQL
3030
namespace
3131
NoSQL
32+
OpenTelemetry
3233
ORM
3334
Packagist
3435
PhpRedis

Diff for: .github/workflows/build.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
redis-version:
21-
- "8.0-M03" # 8.0 milestone 4
21+
- "8.0-M05" # 8.0 milestone 5
2222
- "7.4.2" # should use redis stack 7.4
2323
go-version:
2424
- "1.23.x"
@@ -43,7 +43,7 @@ jobs:
4343
4444
# Mapping of redis version to redis testing containers
4545
declare -A redis_version_mapping=(
46-
["8.0-M03"]="8.0-M04-pre"
46+
["8.0-M05"]="8.0-M05-pre"
4747
["7.4.2"]="rs-7.4.0-v2"
4848
)
4949
if [[ -v redis_version_mapping[$REDIS_VERSION] ]]; then
@@ -72,7 +72,7 @@ jobs:
7272
fail-fast: false
7373
matrix:
7474
redis-version:
75-
- "8.0-M03" # 8.0 milestone 4
75+
- "8.0-M05" # 8.0 milestone 5
7676
- "7.4.2" # should use redis stack 7.4
7777
- "7.2.7" # should redis stack 7.2
7878
go-version:

Diff for: .github/workflows/golangci-lint.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ jobs:
2121
steps:
2222
- uses: actions/checkout@v4
2323
- name: golangci-lint
24-
uses: golangci/[email protected]
24+
uses: golangci/[email protected]
25+
with:
26+
verify: false # disable verifying the configuration since golangci is currently introducing breaking changes in the configuration
27+

Diff for: .github/workflows/test-redis-enterprise.yml

-1
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,4 @@ jobs:
5454
--ginkgo.skip-file="sentinel_test.go" \
5555
--ginkgo.skip-file="osscluster_test.go" \
5656
--ginkgo.skip-file="pubsub_test.go" \
57-
--ginkgo.skip-file="gears_commands_test.go" \
5857
--ginkgo.label-filter='!NonRedisEnterprise'

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test.ci:
1717
(cd "$${dir}" && \
1818
go mod tidy -compat=1.18 && \
1919
go vet && \
20-
go test -coverprofile=coverage.txt -covermode=atomic ./... -race); \
20+
go test -v -coverprofile=coverage.txt -covermode=atomic ./... -race); \
2121
done
2222
cd internal/customvet && go build .
2323
go vet -vettool ./internal/customvet/customvet

Diff for: README.md

+55-12
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@
66
[![codecov](https://codecov.io/github/redis/go-redis/graph/badge.svg?token=tsrCZKuSSw)](https://codecov.io/github/redis/go-redis)
77
[![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj)
88

9-
> go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace).
10-
> Uptrace is an open-source APM tool that supports distributed tracing, metrics, and logs. You can
11-
> use it to monitor applications and set up automatic alerts to receive notifications via email,
12-
> Slack, Telegram, and others.
13-
>
14-
> See [OpenTelemetry](https://github.com/redis/go-redis/tree/master/example/otel) example which
15-
> demonstrates how you can use Uptrace to monitor go-redis.
9+
> go-redis is the official Redis client library for the Go programming language. It offers a straightforward interface for interacting with Redis servers.
1610
1711
## Supported versions
1812

@@ -173,6 +167,24 @@ func ExampleClient() *redis.Client {
173167

174168
```
175169

170+
### Instrument with OpenTelemetry
171+
172+
```go
173+
import (
174+
"github.com/redis/go-redis/v9"
175+
"github.com/redis/go-redis/extra/redisotel/v9"
176+
"errors"
177+
)
178+
179+
func main() {
180+
...
181+
rdb := redis.NewClient(&redis.Options{...})
182+
183+
if err := errors.Join(redisotel.InstrumentTracing(rdb), redisotel.InstrumentMetrics(rdb)); err != nil {
184+
log.Fatal(err)
185+
}
186+
```
187+
176188
177189
### Advanced Configuration
178190
@@ -184,16 +196,18 @@ By default, go-redis automatically sends the client library name and version dur
184196
185197
#### Disabling Identity Verification
186198
187-
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIndentity` configuration option exists. In V10 of this library, `DisableIndentity` will become `DisableIdentity` in order to fix the associated typo.
199+
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIdentity` configuration option exists.
200+
Initially there was a typo and the option was named `DisableIndentity` instead of `DisableIdentity`. The misspelled option is marked as Deprecated and will be removed in V10 of this library.
201+
Although both options will work at the moment, the correct option is `DisableIdentity`. The deprecated option will be removed in V10 of this library, so please use the correct option name to avoid any issues.
188202
189-
To disable verification, set the `DisableIndentity` option to `true` in the Redis client options:
203+
To disable verification, set the `DisableIdentity` option to `true` in the Redis client options:
190204
191205
```go
192206
rdb := redis.NewClient(&redis.Options{
193207
Addr: "localhost:6379",
194208
Password: "",
195209
DB: 0,
196-
DisableIndentity: true, // Disable set-info on connect
210+
DisableIdentity: true, // Disable set-info on connect
197211
})
198212
```
199213
@@ -215,9 +229,30 @@ res1, err := client.FTSearchWithArgs(ctx, "txt", "foo bar", &redis.FTSearchOptio
215229
val1 := client.FTSearchWithArgs(ctx, "txt", "foo bar", &redis.FTSearchOptions{}).RawVal()
216230
```
217231
218-
## Contributing
232+
#### Redis-Search Default Dialect
219233
220-
Please see [out contributing guidelines](CONTRIBUTING.md) to help us improve this library!
234+
In the Redis-Search module, **the default dialect is 2**. If needed, you can explicitly specify a different dialect using the appropriate configuration in your queries.
235+
236+
**Important**: Be aware that the query dialect may impact the results returned. If needed, you can revert to a different dialect version by passing the desired dialect in the arguments of the command you want to execute.
237+
For example:
238+
```
239+
res2, err := rdb.FTSearchWithArgs(ctx,
240+
"idx:bicycle",
241+
"@pickup_zone:[CONTAINS $bike]",
242+
&redis.FTSearchOptions{
243+
Params: map[string]interface{}{
244+
"bike": "POINT(-0.1278 51.5074)",
245+
},
246+
DialectVersion: 3,
247+
},
248+
).Result()
249+
```
250+
You can find further details in the [query dialect documentation](https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/dialects/).
251+
252+
## Contributing
253+
We welcome contributions to the go-redis library! If you have a bug fix, feature request, or improvement, please open an issue or pull request on GitHub.
254+
We appreciate your help in making go-redis better for everyone.
255+
If you are interested in contributing to the go-redis library, please check out our [contributing guidelines](CONTRIBUTING.md) for more information on how to get started.
221256
222257
## Look and feel
223258
@@ -297,6 +332,14 @@ REDIS_PORT=9999 go test <your options>
297332
298333
## Contributors
299334
335+
> The go-redis project was originally initiated by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace).
336+
> Uptrace is an open-source APM tool that supports distributed tracing, metrics, and logs. You can
337+
> use it to monitor applications and set up automatic alerts to receive notifications via email,
338+
> Slack, Telegram, and others.
339+
>
340+
> See [OpenTelemetry](https://github.com/redis/go-redis/tree/master/example/otel) example which
341+
> demonstrates how you can use Uptrace to monitor go-redis.
342+
300343
Thanks to all the people who already contributed!
301344
302345
<a href="https://github.com/redis/go-redis/graphs/contributors">

Diff for: bench_decode_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func NewClientStub(resp []byte) *ClientStub {
3030
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
3131
return stub.stubConn(initHello), nil
3232
},
33-
DisableIndentity: true,
33+
DisableIdentity: true,
3434
})
3535
return stub
3636
}
@@ -46,7 +46,7 @@ func NewClusterClientStub(resp []byte) *ClientStub {
4646
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
4747
return stub.stubConn(initHello), nil
4848
},
49-
DisableIndentity: true,
49+
DisableIdentity: true,
5050

5151
ClusterSlots: func(_ context.Context) ([]ClusterSlot, error) {
5252
return []ClusterSlot{

Diff for: commands.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ type Cmdable interface {
211211
ACLCmdable
212212
BitMapCmdable
213213
ClusterCmdable
214-
GearsCmdable
215214
GenericCmdable
216215
GeoCmdable
217216
HashCmdable
@@ -423,6 +422,12 @@ func (c cmdable) Ping(ctx context.Context) *StatusCmd {
423422
return cmd
424423
}
425424

425+
func (c cmdable) Do(ctx context.Context, args ...interface{}) *Cmd {
426+
cmd := NewCmd(ctx, args...)
427+
_ = c(ctx, cmd)
428+
return cmd
429+
}
430+
426431
func (c cmdable) Quit(_ context.Context) *StatusCmd {
427432
panic("not implemented")
428433
}

Diff for: commands_test.go

+148-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ var _ = Describe("Commands", func() {
8484
Expect(ping.Val()).To(Equal("PONG"))
8585
})
8686

87+
It("should Ping with Do method", func() {
88+
result := client.Conn().Do(ctx, "PING")
89+
Expect(result.Err()).NotTo(HaveOccurred())
90+
Expect(result.Val()).To(Equal("PONG"))
91+
})
92+
8793
It("should Wait", func() {
8894
const wait = 3 * time.Second
8995

@@ -2659,7 +2665,6 @@ var _ = Describe("Commands", func() {
26592665
Expect(res).To(Equal([]int64{1, 1, -2}))
26602666
})
26612667

2662-
26632668
It("should HPExpire", Label("hash-expiration", "NonRedisEnterprise"), func() {
26642669
SkipBeforeRedisVersion(7.4, "doesn't work with older redis stack images")
26652670
res, err := client.HPExpire(ctx, "no_such_key", 10*time.Second, "field1", "field2", "field3").Result()
@@ -2812,6 +2817,148 @@ var _ = Describe("Commands", func() {
28122817
Expect(err).NotTo(HaveOccurred())
28132818
Expect(res[0]).To(BeNumerically("~", 10*time.Second.Milliseconds(), 1))
28142819
})
2820+
2821+
It("should HGETDEL", Label("hash", "HGETDEL"), func() {
2822+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2823+
2824+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2", "f3", "val3").Err()
2825+
Expect(err).NotTo(HaveOccurred())
2826+
2827+
// Execute HGETDEL on fields f1 and f2.
2828+
res, err := client.HGetDel(ctx, "myhash", "f1", "f2").Result()
2829+
Expect(err).NotTo(HaveOccurred())
2830+
// Expect the returned values for f1 and f2.
2831+
Expect(res).To(Equal([]string{"val1", "val2"}))
2832+
2833+
// Verify that f1 and f2 have been deleted, while f3 remains.
2834+
remaining, err := client.HMGet(ctx, "myhash", "f1", "f2", "f3").Result()
2835+
Expect(err).NotTo(HaveOccurred())
2836+
Expect(remaining[0]).To(BeNil())
2837+
Expect(remaining[1]).To(BeNil())
2838+
Expect(remaining[2]).To(Equal("val3"))
2839+
})
2840+
2841+
It("should return nil responses for HGETDEL on non-existent key", Label("hash", "HGETDEL"), func() {
2842+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2843+
// HGETDEL on a key that does not exist.
2844+
res, err := client.HGetDel(ctx, "nonexistent", "f1", "f2").Result()
2845+
Expect(err).To(BeNil())
2846+
Expect(res).To(Equal([]string{"", ""}))
2847+
})
2848+
2849+
// -----------------------------
2850+
// HGETEX with various TTL options
2851+
// -----------------------------
2852+
It("should HGETEX with EX option", Label("hash", "HGETEX"), func() {
2853+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2854+
2855+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2856+
Expect(err).NotTo(HaveOccurred())
2857+
2858+
// Call HGETEX with EX option and 60 seconds TTL.
2859+
opt := redis.HGetEXOptions{
2860+
ExpirationType: redis.HGetEXExpirationEX,
2861+
ExpirationVal: 60,
2862+
}
2863+
res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
2864+
Expect(err).NotTo(HaveOccurred())
2865+
Expect(res).To(Equal([]string{"val1", "val2"}))
2866+
})
2867+
2868+
It("should HGETEX with PERSIST option", Label("hash", "HGETEX"), func() {
2869+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2870+
2871+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2872+
Expect(err).NotTo(HaveOccurred())
2873+
2874+
// Call HGETEX with PERSIST (no TTL value needed).
2875+
opt := redis.HGetEXOptions{ExpirationType: redis.HGetEXExpirationPERSIST}
2876+
res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
2877+
Expect(err).NotTo(HaveOccurred())
2878+
Expect(res).To(Equal([]string{"val1", "val2"}))
2879+
})
2880+
2881+
It("should HGETEX with EXAT option", Label("hash", "HGETEX"), func() {
2882+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2883+
2884+
err := client.HSet(ctx, "myhash", "f1", "val1", "f2", "val2").Err()
2885+
Expect(err).NotTo(HaveOccurred())
2886+
2887+
// Set expiration at a specific Unix timestamp (60 seconds from now).
2888+
expireAt := time.Now().Add(60 * time.Second).Unix()
2889+
opt := redis.HGetEXOptions{
2890+
ExpirationType: redis.HGetEXExpirationEXAT,
2891+
ExpirationVal: expireAt,
2892+
}
2893+
res, err := client.HGetEXWithArgs(ctx, "myhash", &opt, "f1", "f2").Result()
2894+
Expect(err).NotTo(HaveOccurred())
2895+
Expect(res).To(Equal([]string{"val1", "val2"}))
2896+
})
2897+
2898+
// -----------------------------
2899+
// HSETEX with FNX/FXX options
2900+
// -----------------------------
2901+
It("should HSETEX with FNX condition", Label("hash", "HSETEX"), func() {
2902+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2903+
2904+
opt := redis.HSetEXOptions{
2905+
Condition: redis.HSetEXFNX,
2906+
ExpirationType: redis.HSetEXExpirationEX,
2907+
ExpirationVal: 60,
2908+
}
2909+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1").Result()
2910+
Expect(err).NotTo(HaveOccurred())
2911+
Expect(res).To(Equal(int64(1)))
2912+
2913+
opt = redis.HSetEXOptions{
2914+
Condition: redis.HSetEXFNX,
2915+
ExpirationType: redis.HSetEXExpirationEX,
2916+
ExpirationVal: 60,
2917+
}
2918+
res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val2").Result()
2919+
Expect(err).NotTo(HaveOccurred())
2920+
Expect(res).To(Equal(int64(0)))
2921+
})
2922+
2923+
It("should HSETEX with FXX condition", Label("hash", "HSETEX"), func() {
2924+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2925+
2926+
err := client.HSet(ctx, "myhash", "f2", "val1").Err()
2927+
Expect(err).NotTo(HaveOccurred())
2928+
2929+
opt := redis.HSetEXOptions{
2930+
Condition: redis.HSetEXFXX,
2931+
ExpirationType: redis.HSetEXExpirationEX,
2932+
ExpirationVal: 60,
2933+
}
2934+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f2", "val2").Result()
2935+
Expect(err).NotTo(HaveOccurred())
2936+
Expect(res).To(Equal(int64(1)))
2937+
opt = redis.HSetEXOptions{
2938+
Condition: redis.HSetEXFXX,
2939+
ExpirationType: redis.HSetEXExpirationEX,
2940+
ExpirationVal: 60,
2941+
}
2942+
res, err = client.HSetEXWithArgs(ctx, "myhash", &opt, "f3", "val3").Result()
2943+
Expect(err).NotTo(HaveOccurred())
2944+
Expect(res).To(Equal(int64(0)))
2945+
})
2946+
2947+
It("should HSETEX with multiple field operations", Label("hash", "HSETEX"), func() {
2948+
SkipBeforeRedisVersion(7.9, "requires Redis 8.x")
2949+
2950+
opt := redis.HSetEXOptions{
2951+
ExpirationType: redis.HSetEXExpirationEX,
2952+
ExpirationVal: 60,
2953+
}
2954+
res, err := client.HSetEXWithArgs(ctx, "myhash", &opt, "f1", "val1", "f2", "val2").Result()
2955+
Expect(err).NotTo(HaveOccurred())
2956+
Expect(res).To(Equal(int64(1)))
2957+
2958+
values, err := client.HMGet(ctx, "myhash", "f1", "f2").Result()
2959+
Expect(err).NotTo(HaveOccurred())
2960+
Expect(values).To(Equal([]interface{}{"val1", "val2"}))
2961+
})
28152962
})
28162963

28172964
Describe("hyperloglog", func() {

0 commit comments

Comments
 (0)