redis/example_test.go

664 lines
14 KiB
Go
Raw Permalink Normal View History

package redis_test
import (
2020-03-11 17:26:42 +03:00
"context"
"errors"
"fmt"
"sync"
2015-05-23 14:15:05 +03:00
"time"
2022-06-04 17:39:21 +03:00
"github.com/go-redis/redis/v9"
)
2020-07-16 09:52:07 +03:00
var (
ctx = context.Background()
rdb *redis.Client
)
2014-05-11 11:42:40 +04:00
func init() {
2019-08-18 17:24:17 +03:00
rdb = redis.NewClient(&redis.Options{
2016-03-19 17:55:22 +03:00
Addr: ":6379",
DialTimeout: 10 * time.Second,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
PoolSize: 10,
PoolTimeout: 30 * time.Second,
})
}
2015-05-02 16:19:22 +03:00
func ExampleNewClient() {
2019-08-18 17:24:17 +03:00
rdb := redis.NewClient(&redis.Options{
2019-01-13 11:36:38 +03:00
Addr: "localhost:6379", // use default Addr
Password: "", // no password set
DB: 0, // use default DB
2014-05-11 11:42:40 +04:00
})
2014-07-13 16:49:33 +04:00
2020-03-11 17:26:42 +03:00
pong, err := rdb.Ping(ctx).Result()
2014-07-13 16:49:33 +04:00
fmt.Println(pong, err)
// Output: PONG <nil>
}
2017-06-09 13:55:45 +03:00
func ExampleParseURL() {
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1?dial_timeout=5s")
2017-06-09 13:55:45 +03:00
if err != nil {
panic(err)
}
fmt.Println("addr is", opt.Addr)
fmt.Println("db is", opt.DB)
fmt.Println("password is", opt.Password)
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
fmt.Println("dial timeout is", opt.DialTimeout)
2017-06-09 13:55:45 +03:00
// Create client as usually.
_ = redis.NewClient(opt)
// Output: addr is localhost:6379
// db is 1
// password is qwerty
chore: sync master (#2051) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey <golang@88.com> * XAutoClaim changed the return value Signed-off-by: monkey <golang@88.com> * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t <golang@88.com> * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t <golang@88.com> * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com> * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t <golang@88.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t <golang@88.com> * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t <golang@88.com> * remove runGoroutine Signed-off-by: monkey92t <golang@88.com> * pool.popIdle add p.closed check Signed-off-by: monkey92t <golang@88.com> * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t <golang@88.com> * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t <golang@88.com> Co-authored-by: monkey92t <golang@88.com> * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky <ponizovsky@gmail.com> Co-authored-by: Bogdan Drutu <bogdandrutu@gmail.com> Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B <kishancs46@gmail.com> Co-authored-by: Dominik Menke <dom@digineo.de> Co-authored-by: Gökhan Özeloğlu <gozeloglu@gmail.com> Co-authored-by: Justin Sievenpiper <justin@sievenpiper.co> Co-authored-by: Алексей Романовский <aromanovsky@epiphan.com> Co-authored-by: Stavros Panakakakis <stavrospanakakis@gmail.com> Co-authored-by: Pau Freixes <pfreixes@gmail.com> Co-authored-by: Ethan Hur <ethan0311@gmail.com> Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal <kristinnardalsecondary@gmail.com> Co-authored-by: ffenix113 <razerer@bigmir.net> Co-authored-by: Bastien Penavayre <bastienPenava@gmail.com> Co-authored-by: James3 Li(李麒傑) <james3_li@asus.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: gzjiangtao2014 <gzjiangtao2014@corp.netease.com> Co-authored-by: Nelz <nelz9999@users.noreply.github.com> Co-authored-by: Daniel Richter <Nexyz9@gmail.com> Co-authored-by: Seyed Ali Ghaffari <ali.ghaffari@outlook.com> Co-authored-by: lintanghui <lintanghui@bilibili.com> Co-authored-by: hidu <duv123+github@gmail.com> Co-authored-by: Jonas Lergell <jonas.lergell@volvocars.com> Co-authored-by: Alex Kahn <alexanderkahn@gmail.com>
2022-03-19 07:40:31 +03:00
// dial timeout is 5s
2017-06-09 13:55:45 +03:00
}
2014-07-13 16:49:33 +04:00
func ExampleNewFailoverClient() {
// See http://redis.io/topics/sentinel for instructions how to
// setup Redis Sentinel.
2019-08-18 17:24:17 +03:00
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
2015-01-25 15:33:30 +03:00
MasterName: "master",
2014-07-13 16:49:33 +04:00
SentinelAddrs: []string{":26379"},
})
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
}
func ExampleNewClusterClient() {
// See http://redis.io/topics/cluster-tutorial for instructions
// how to setup Redis Cluster.
2019-08-18 17:24:17 +03:00
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
})
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
}
2018-06-29 10:45:05 +03:00
// Following example creates a cluster from 2 master nodes and 2 slave nodes
// without using cluster mode or Redis Sentinel.
func ExampleNewClusterClient_manualSetup() {
2018-07-18 15:28:51 +03:00
// clusterSlots returns cluster slots information.
// It can use service like ZooKeeper to maintain configuration information
// and Cluster.ReloadState to manually trigger state reloading.
2020-09-09 15:27:17 +03:00
clusterSlots := func(ctx context.Context) ([]redis.ClusterSlot, error) {
2018-06-29 10:45:05 +03:00
slots := []redis.ClusterSlot{
// First node with 1 master and 1 slave.
{
Start: 0,
End: 8191,
Nodes: []redis.ClusterNode{{
Addr: ":7000", // master
}, {
Addr: ":8000", // 1st slave
}},
},
// Second node with 1 master and 1 slave.
{
Start: 8192,
End: 16383,
Nodes: []redis.ClusterNode{{
Addr: ":7001", // master
}, {
Addr: ":8001", // 1st slave
}},
},
}
return slots, nil
}
2019-08-18 17:24:17 +03:00
rdb := redis.NewClusterClient(&redis.ClusterOptions{
2018-07-18 15:28:51 +03:00
ClusterSlots: clusterSlots,
2018-06-29 10:45:05 +03:00
RouteRandomly: true,
})
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
2018-06-29 10:45:05 +03:00
2018-07-18 15:28:51 +03:00
// ReloadState reloads cluster state. It calls ClusterSlots func
// to get cluster slots information.
2020-09-11 15:52:38 +03:00
rdb.ReloadState(ctx)
2018-06-29 10:45:05 +03:00
}
func ExampleNewRing() {
2019-08-18 17:24:17 +03:00
rdb := redis.NewRing(&redis.RingOptions{
Addrs: map[string]string{
"shard1": ":7000",
"shard2": ":7001",
"shard3": ":7002",
},
})
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
}
2014-05-11 11:42:40 +04:00
func ExampleClient() {
2020-03-11 17:26:42 +03:00
err := rdb.Set(ctx, "key", "value", 0).Err()
2015-05-23 14:33:33 +03:00
if err != nil {
2014-07-31 16:18:23 +04:00
panic(err)
}
2020-03-11 17:26:42 +03:00
val, err := rdb.Get(ctx, "key").Result()
2015-05-23 14:33:33 +03:00
if err != nil {
panic(err)
}
fmt.Println("key", val)
2020-03-11 17:26:42 +03:00
val2, err := rdb.Get(ctx, "missing_key").Result()
2015-05-23 14:33:33 +03:00
if err == redis.Nil {
2018-08-06 13:59:15 +03:00
fmt.Println("missing_key does not exist")
2015-05-23 14:33:33 +03:00
} else if err != nil {
panic(err)
} else {
2018-08-06 13:59:15 +03:00
fmt.Println("missing_key", val2)
2015-05-23 14:33:33 +03:00
}
// Output: key value
2018-08-06 13:59:15 +03:00
// missing_key does not exist
2014-07-31 16:18:23 +04:00
}
func ExampleConn() {
conn := rdb.Conn()
2020-03-11 17:26:42 +03:00
err := conn.ClientSetName(ctx, "foobar").Err()
if err != nil {
panic(err)
}
// Open other connections.
for i := 0; i < 10; i++ {
2020-03-11 17:26:42 +03:00
go rdb.Ping(ctx)
}
2020-03-11 17:26:42 +03:00
s, err := conn.ClientGetName(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println(s)
// Output: foobar
}
2015-08-07 17:02:17 +03:00
func ExampleClient_Set() {
// Last argument is expiration. Zero means the key has no
// expiration time.
2020-03-11 17:26:42 +03:00
err := rdb.Set(ctx, "key", "value", 0).Err()
2015-08-07 17:02:17 +03:00
if err != nil {
panic(err)
}
// key2 will expire in an hour.
2020-03-11 17:26:42 +03:00
err = rdb.Set(ctx, "key2", "value", time.Hour).Err()
2015-08-07 17:02:17 +03:00
if err != nil {
panic(err)
}
}
func ExampleClient_SetEx() {
err := rdb.SetEx(ctx, "key", "value", time.Hour).Err()
2020-10-22 21:38:36 +03:00
if err != nil {
panic(err)
}
}
2014-07-31 16:18:23 +04:00
func ExampleClient_Incr() {
2020-03-11 17:26:42 +03:00
result, err := rdb.Incr(ctx, "counter").Result()
2017-08-04 11:51:14 +03:00
if err != nil {
2014-07-31 16:18:23 +04:00
panic(err)
}
2017-08-04 11:51:14 +03:00
fmt.Println(result)
// Output: 1
}
2015-11-24 10:09:53 +03:00
func ExampleClient_BLPop() {
2020-03-11 17:26:42 +03:00
if err := rdb.RPush(ctx, "queue", "message").Err(); err != nil {
2015-11-24 10:09:53 +03:00
panic(err)
}
2019-08-18 17:24:17 +03:00
// use `rdb.BLPop(0, "queue")` for infinite waiting time
2020-03-11 17:26:42 +03:00
result, err := rdb.BLPop(ctx, 1*time.Second, "queue").Result()
2015-11-24 10:09:53 +03:00
if err != nil {
panic(err)
}
fmt.Println(result[0], result[1])
// Output: queue message
}
2015-08-19 11:44:46 +03:00
func ExampleClient_Scan() {
2020-03-11 17:26:42 +03:00
rdb.FlushDB(ctx)
2015-08-19 11:44:46 +03:00
for i := 0; i < 33; i++ {
2020-03-11 17:26:42 +03:00
err := rdb.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
2015-08-19 11:44:46 +03:00
if err != nil {
panic(err)
}
}
var cursor uint64
2015-08-19 11:44:46 +03:00
var n int
for {
var keys []string
var err error
2020-03-11 17:26:42 +03:00
keys, cursor, err = rdb.Scan(ctx, cursor, "key*", 10).Result()
2015-08-19 11:44:46 +03:00
if err != nil {
panic(err)
}
n += len(keys)
if cursor == 0 {
break
}
}
fmt.Printf("found %d keys\n", n)
// Output: found 33 keys
}
func ExampleClient_ScanType() {
rdb.FlushDB(ctx)
for i := 0; i < 33; i++ {
err := rdb.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
if err != nil {
panic(err)
}
}
var cursor uint64
var n int
for {
var keys []string
var err error
keys, cursor, err = rdb.ScanType(ctx, cursor, "key*", 10, "string").Result()
if err != nil {
panic(err)
}
n += len(keys)
if cursor == 0 {
break
}
}
fmt.Printf("found %d keys\n", n)
// Output: found 33 keys
}
2022-10-05 10:06:54 +03:00
// ExampleClient_ScanType_hashType uses the keyType "hash".
func ExampleClient_ScanType_hashType() {
rdb.FlushDB(ctx)
for i := 0; i < 33; i++ {
err := rdb.HSet(context.TODO(), fmt.Sprintf("key%d", i), "value", "foo").Err()
if err != nil {
panic(err)
}
}
var allKeys []string
var cursor uint64
var err error
for {
var keysFromScan []string
keysFromScan, cursor, err = rdb.ScanType(context.TODO(), cursor, "key*", 10, "hash").Result()
if err != nil {
panic(err)
}
allKeys = append(allKeys, keysFromScan...)
if cursor == 0 {
break
}
}
2022-10-04 15:09:05 +03:00
fmt.Printf("%d keys ready for use", len(allKeys))
// Output: 33 keys ready for use
}
// ExampleMapStringStringCmd_Scan shows how to scan the results of a map fetch
2021-02-02 13:58:35 +03:00
// into a struct.
func ExampleMapStringStringCmd_Scan() {
2021-02-02 13:58:35 +03:00
rdb.FlushDB(ctx)
err := rdb.HMSet(ctx, "map",
"name", "hello",
"count", 123,
"correct", true).Err()
if err != nil {
panic(err)
}
// Get the map. The same approach works for HmGet().
res := rdb.HGetAll(ctx, "map")
if res.Err() != nil {
panic(err)
}
type data struct {
Name string `redis:"name"`
Count int `redis:"count"`
Correct bool `redis:"correct"`
}
// Scan the results into the struct.
var d data
if err := res.Scan(&d); err != nil {
panic(err)
}
fmt.Println(d)
// Output: {hello 123 true}
}
// ExampleSliceCmd_Scan shows how to scan the results of a multi key fetch
// into a struct.
func ExampleSliceCmd_Scan() {
rdb.FlushDB(ctx)
err := rdb.MSet(ctx,
"name", "hello",
"count", 123,
"correct", true).Err()
if err != nil {
panic(err)
}
res := rdb.MGet(ctx, "name", "count", "empty", "correct")
if res.Err() != nil {
panic(err)
}
type data struct {
Name string `redis:"name"`
Count int `redis:"count"`
Correct bool `redis:"correct"`
}
// Scan the results into the struct.
var d data
if err := res.Scan(&d); err != nil {
panic(err)
}
fmt.Println(d)
// Output: {hello 123 true}
}
2014-05-11 11:42:40 +04:00
func ExampleClient_Pipelined() {
var incr *redis.IntCmd
2020-03-11 17:26:42 +03:00
_, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
incr = pipe.Incr(ctx, "pipelined_counter")
pipe.Expire(ctx, "pipelined_counter", time.Hour)
2014-07-02 18:55:00 +04:00
return nil
})
fmt.Println(incr.Val(), err)
// Output: 1 <nil>
}
2016-12-22 14:14:34 +03:00
func ExampleClient_Pipeline() {
2019-08-18 17:24:17 +03:00
pipe := rdb.Pipeline()
2020-03-11 17:26:42 +03:00
incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)
2016-12-22 14:14:34 +03:00
// Execute
//
// INCR pipeline_counter
// EXPIRE pipeline_counts 3600
//
2019-08-18 17:24:17 +03:00
// using one rdb-server roundtrip.
2020-03-11 17:26:42 +03:00
_, err := pipe.Exec(ctx)
2016-12-22 14:14:34 +03:00
fmt.Println(incr.Val(), err)
// Output: 1 <nil>
}
func ExampleClient_TxPipelined() {
var incr *redis.IntCmd
2020-03-11 17:26:42 +03:00
_, err := rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
incr = pipe.Incr(ctx, "tx_pipelined_counter")
pipe.Expire(ctx, "tx_pipelined_counter", time.Hour)
2016-12-22 14:14:34 +03:00
return nil
})
fmt.Println(incr.Val(), err)
// Output: 1 <nil>
}
func ExampleClient_TxPipeline() {
2019-08-18 17:24:17 +03:00
pipe := rdb.TxPipeline()
2016-12-22 14:14:34 +03:00
2020-03-11 17:26:42 +03:00
incr := pipe.Incr(ctx, "tx_pipeline_counter")
pipe.Expire(ctx, "tx_pipeline_counter", time.Hour)
2016-12-22 14:14:34 +03:00
// Execute
//
// MULTI
// INCR pipeline_counter
// EXPIRE pipeline_counts 3600
// EXEC
//
2019-08-18 17:24:17 +03:00
// using one rdb-server roundtrip.
2020-03-11 17:26:42 +03:00
_, err := pipe.Exec(ctx)
fmt.Println(incr.Val(), err)
// Output: 1 <nil>
}
func ExampleClient_Watch() {
2020-06-10 15:04:12 +03:00
const maxRetries = 1000
2015-11-15 11:23:00 +03:00
2020-06-10 15:04:12 +03:00
// Increment transactionally increments key using GET and SET commands.
increment := func(key string) error {
2020-06-10 15:04:12 +03:00
// Transactional function.
txf := func(tx *redis.Tx) error {
2020-06-10 15:04:12 +03:00
// Get current value or zero.
2020-03-11 17:26:42 +03:00
n, err := tx.Get(ctx, key).Int()
2016-05-02 15:54:15 +03:00
if err != nil && err != redis.Nil {
return err
}
2020-06-10 15:04:12 +03:00
// Actual opperation (local in optimistic lock).
n++
2021-07-22 05:27:46 +03:00
// Operation is committed only if the watched keys remain unchanged.
2020-03-11 17:26:42 +03:00
_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, key, n, 0)
2016-05-02 15:54:15 +03:00
return nil
})
return err
2015-11-15 11:23:00 +03:00
}
2020-06-10 15:04:12 +03:00
for i := 0; i < maxRetries; i++ {
2020-03-11 17:26:42 +03:00
err := rdb.Watch(ctx, txf, key)
2020-06-10 15:04:12 +03:00
if err == nil {
// Success.
return nil
}
if err == redis.TxFailedErr {
// Optimistic lock lost. Retry.
continue
}
2020-06-10 15:04:12 +03:00
// Return any other error.
return err
}
2020-06-10 15:04:12 +03:00
return errors.New("increment reached maximum number of retries")
2014-05-11 11:42:40 +04:00
}
var wg sync.WaitGroup
2020-06-10 15:04:12 +03:00
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
if err := increment("counter3"); err != nil {
fmt.Println("increment error:", err)
}
}()
2014-05-11 11:42:40 +04:00
}
wg.Wait()
2020-03-11 17:26:42 +03:00
n, err := rdb.Get(ctx, "counter3").Int()
fmt.Println("ended with", n, err)
// Output: ended with 100 <nil>
}
func ExamplePubSub() {
2020-03-11 17:26:42 +03:00
pubsub := rdb.Subscribe(ctx, "mychannel1")
2018-07-24 10:48:14 +03:00
// Wait for confirmation that subscription is created before publishing anything.
2020-03-11 17:26:42 +03:00
_, err := pubsub.Receive(ctx)
2018-07-24 10:48:14 +03:00
if err != nil {
panic(err)
}
2018-07-24 09:41:14 +03:00
// Go channel which receives messages.
ch := pubsub.Channel()
2018-07-24 09:41:14 +03:00
// Publish a message.
2020-03-11 17:26:42 +03:00
err = rdb.Publish(ctx, "mychannel1", "hello").Err()
2015-09-06 13:50:16 +03:00
if err != nil {
panic(err)
}
2018-07-24 14:50:16 +03:00
time.AfterFunc(time.Second, func() {
// When pubsub is closed channel is closed too.
_ = pubsub.Close()
})
// Consume messages.
for msg := range ch {
2018-07-24 14:50:16 +03:00
fmt.Println(msg.Channel, msg.Payload)
}
2018-07-24 09:41:14 +03:00
// Output: mychannel1 hello
2015-09-06 13:50:16 +03:00
}
func ExamplePubSub_Receive() {
2020-03-11 17:26:42 +03:00
pubsub := rdb.Subscribe(ctx, "mychannel2")
2015-09-06 13:50:16 +03:00
defer pubsub.Close()
2016-03-15 15:45:04 +03:00
for i := 0; i < 2; i++ {
2015-11-22 15:44:38 +03:00
// ReceiveTimeout is a low level API. Use ReceiveMessage instead.
2020-03-11 17:26:42 +03:00
msgi, err := pubsub.ReceiveTimeout(ctx, time.Second)
2015-05-23 14:15:05 +03:00
if err != nil {
2016-03-14 17:51:46 +03:00
break
2015-05-23 14:15:05 +03:00
}
2015-05-23 14:15:05 +03:00
switch msg := msgi.(type) {
case *redis.Subscription:
2016-03-14 17:51:46 +03:00
fmt.Println("subscribed to", msg.Channel)
2017-07-01 13:22:39 +03:00
2020-03-11 17:26:42 +03:00
_, err := rdb.Publish(ctx, "mychannel2", "hello").Result()
2017-07-01 13:22:39 +03:00
if err != nil {
panic(err)
}
2015-05-23 14:15:05 +03:00
case *redis.Message:
2016-03-14 17:51:46 +03:00
fmt.Println("received", msg.Payload, "from", msg.Channel)
2015-05-23 14:15:05 +03:00
default:
2017-07-01 13:22:39 +03:00
panic("unreached")
2015-05-23 14:15:05 +03:00
}
}
2019-08-18 17:24:17 +03:00
// sent message to 1 rdb
2016-03-14 17:51:46 +03:00
// received hello from mychannel2
}
2014-05-11 11:42:40 +04:00
func ExampleScript() {
2015-06-16 10:31:21 +03:00
IncrByXX := redis.NewScript(`
if redis.call("GET", KEYS[1]) ~= false then
return redis.call("INCRBY", KEYS[1], ARGV[1])
end
return false
`)
2020-03-11 17:26:42 +03:00
n, err := IncrByXX.Run(ctx, rdb, []string{"xx_counter"}, 2).Result()
2015-06-16 10:31:21 +03:00
fmt.Println(n, err)
2014-05-11 11:42:40 +04:00
2020-03-11 17:26:42 +03:00
err = rdb.Set(ctx, "xx_counter", "40", 0).Err()
2015-06-16 10:31:21 +03:00
if err != nil {
panic(err)
}
2014-05-11 11:42:40 +04:00
2020-03-11 17:26:42 +03:00
n, err = IncrByXX.Run(ctx, rdb, []string{"xx_counter"}, 2).Result()
2015-06-16 10:31:21 +03:00
fmt.Println(n, err)
2014-05-11 11:42:40 +04:00
2015-06-16 10:31:21 +03:00
// Output: <nil> redis: nil
// 42 <nil>
}
2014-05-11 11:42:40 +04:00
func Example_customCommand() {
2020-03-11 17:26:42 +03:00
Get := func(ctx context.Context, rdb *redis.Client, key string) *redis.StringCmd {
cmd := redis.NewStringCmd(ctx, "get", key)
rdb.Process(ctx, cmd)
2014-05-11 11:42:40 +04:00
return cmd
}
2020-03-11 17:26:42 +03:00
v, err := Get(ctx, rdb, "key_does_not_exist").Result()
2014-05-11 11:42:40 +04:00
fmt.Printf("%q %s", v, err)
// Output: "" redis: nil
}
2016-04-13 11:52:47 +03:00
2018-08-12 11:11:01 +03:00
func Example_customCommand2() {
2020-03-11 17:26:42 +03:00
v, err := rdb.Do(ctx, "get", "key_does_not_exist").Text()
2018-08-12 11:11:01 +03:00
fmt.Printf("%q %s", v, err)
// Output: "" redis: nil
}
2016-04-13 11:52:47 +03:00
func ExampleScanIterator() {
2020-03-11 17:26:42 +03:00
iter := rdb.Scan(ctx, 0, "", 0).Iterator()
for iter.Next(ctx) {
2016-04-13 11:52:47 +03:00
fmt.Println(iter.Val())
}
if err := iter.Err(); err != nil {
panic(err)
}
}
func ExampleScanCmd_Iterator() {
2020-03-11 17:26:42 +03:00
iter := rdb.Scan(ctx, 0, "", 0).Iterator()
for iter.Next(ctx) {
2016-04-13 11:52:47 +03:00
fmt.Println(iter.Val())
}
if err := iter.Err(); err != nil {
panic(err)
}
}
2017-02-17 13:12:06 +03:00
func ExampleNewUniversalClient_simple() {
2019-08-18 17:24:17 +03:00
rdb := redis.NewUniversalClient(&redis.UniversalOptions{
2017-02-17 13:12:06 +03:00
Addrs: []string{":6379"},
})
2019-08-18 17:24:17 +03:00
defer rdb.Close()
2017-02-17 13:12:06 +03:00
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
2017-02-17 13:12:06 +03:00
}
func ExampleNewUniversalClient_failover() {
2019-08-18 17:24:17 +03:00
rdb := redis.NewUniversalClient(&redis.UniversalOptions{
2017-02-17 13:12:06 +03:00
MasterName: "master",
Addrs: []string{":26379"},
})
2019-08-18 17:24:17 +03:00
defer rdb.Close()
2017-02-17 13:12:06 +03:00
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
2017-02-17 13:12:06 +03:00
}
func ExampleNewUniversalClient_cluster() {
2019-08-18 17:24:17 +03:00
rdb := redis.NewUniversalClient(&redis.UniversalOptions{
2017-02-17 13:12:06 +03:00
Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
})
2019-08-18 17:24:17 +03:00
defer rdb.Close()
2017-02-17 13:12:06 +03:00
2020-03-11 17:26:42 +03:00
rdb.Ping(ctx)
2017-02-17 13:12:06 +03:00
}
2020-06-11 10:24:04 +03:00
2020-09-09 17:42:05 +03:00
func ExampleClient_SlowLogGet() {
2020-09-09 12:49:45 +03:00
const key = "slowlog-log-slower-than"
old := rdb.ConfigGet(ctx, key).Val()
rdb.ConfigSet(ctx, key, "0")
defer rdb.ConfigSet(ctx, key, old[key])
2020-09-09 12:49:45 +03:00
if err := rdb.Do(ctx, "slowlog", "reset").Err(); err != nil {
panic(err)
2020-06-11 10:24:04 +03:00
}
2020-09-09 12:49:45 +03:00
2020-06-11 10:24:04 +03:00
rdb.Set(ctx, "test", "true", 0)
2020-09-09 12:49:45 +03:00
2020-09-09 17:42:05 +03:00
result, err := rdb.SlowLogGet(ctx, -1).Result()
2020-09-09 12:49:45 +03:00
if err != nil {
panic(err)
}
fmt.Println(len(result))
// Output: 2
2020-06-11 10:24:04 +03:00
}