WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 939e695

Browse files
twexlerarschles
andauthored
Adds redis sentinel support (#1554)
* Adds redis sentinel support Fixes #1553 * Fix redis-sentinel test hostnames * Fix redis master name again * Fix redis sentinel port in tests * Upgrade the redis client * Rmoeve accidental config change * Fix default config * Addresses review comments * Add documentation on single flight mechanisms * Fix spelling issues * Fix formatting Co-authored-by: Aaron Schlesinger <[email protected]>
1 parent 3338441 commit 939e695

File tree

12 files changed

+262
-12
lines changed

12 files changed

+262
-12
lines changed

.drone.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ steps:
4646
ATHENS_MONGO_STORAGE_URL: mongodb://mongo:27017
4747
ATHENS_MINIO_ENDPOINT: minio:9000
4848
REDIS_TEST_ENDPOINT: redis:6379
49+
REDIS_SENTINEL_TEST_ENDPOINT: redis-sentinel:26379
50+
REDIS_SENTINEL_TEST_MASTER_NAME: redis-1
51+
REDIS_SENTINEL_TEST_PASSWORD: sekret
4952
PROTECTED_REDIS_TEST_ENDPOINT: protectedredis:6380
5053
ATHENS_PROTECTED_REDIS_PASSWORD: AthensPass1
5154
GCS_SERVICE_ACCOUNT:
@@ -156,13 +159,21 @@ services:
156159
image: redis
157160
ports:
158161
- 6379
162+
- name: redis-sentinel
163+
image: bitnami/redis-sentinel
164+
environment:
165+
REDIS_MASTER_HOST: redis
166+
REDIS_MASTER_SET: redis-1
167+
REDIS_SENTINEL_PASSWORD: sekret
168+
REDIS_SENTINEL_QUORUM: "1"
169+
ports:
170+
- 26379
159171
- name: protectedredis
160172
image: redis
161173
ports:
162174
- 6380
163175
commands:
164176
- "redis-server ./test/redis.conf"
165-
166177
- name: athens-proxy
167178
image: gomods/athens:canary
168179
pull: always

cmd/proxy/actions/app_proxy.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ func getSingleFlight(c *config.Config, checker storage.Checker) (stash.Wrapper,
133133
return nil, fmt.Errorf("Redis config must be present")
134134
}
135135
return stash.WithRedisLock(c.SingleFlight.Redis.Endpoint, c.SingleFlight.Redis.Password, checker)
136+
case "redis-sentinel":
137+
if c.SingleFlight == nil || c.SingleFlight.RedisSentinel == nil {
138+
return nil, fmt.Errorf("Redis config must be present")
139+
}
140+
return stash.WithRedisSentinelLock(
141+
c.SingleFlight.RedisSentinel.Endpoints,
142+
c.SingleFlight.RedisSentinel.MasterName,
143+
c.SingleFlight.RedisSentinel.SentinelPassword,
144+
checker,
145+
)
136146
case "gcp":
137147
if c.StorageType != "gcp" {
138148
return nil, fmt.Errorf("gcp SingleFlight only works with a gcp storage type and not: %v", c.StorageType)

config.dev.toml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ DownloadURL = ""
263263
# and the second request will wait for the first one to finish so that
264264
# it doesn't override the storage.
265265

266-
# Options are ["memory", "etcd", "redis", "gcp", "azureblob"]
266+
# Options are ["memory", "etcd", "redis", "redis-sentinel", "gcp", "azureblob"]
267267

268268
# The default option is "memory" which means that only one instance of Athens
269269
# should be used.
@@ -275,6 +275,10 @@ DownloadURL = ""
275275
# and therefore it will use its strong-consistency features to ensure
276276
# that only one module is ever written even when concurrent saves happen
277277
# at the same time.
278+
# The "redis" single flight will use a single redis instance as a locking mechanism
279+
# for updating the underlying storage
280+
# The "redis-sentinel" single flight works similarly to "redis" but obtains a redis connection
281+
# via a redis-sentinel
278282
# Env override: ATHENS_SINGLE_FLIGHT_TYPE
279283
SingleFlightType = "memory"
280284

@@ -290,6 +294,17 @@ SingleFlightType = "memory"
290294
# TODO(marwan): enable multiple endpoints for redis clusters.
291295
# Env override: ATHENS_REDIS_ENDPOINT
292296
Endpoint = "127.0.0.1:6379"
297+
[SingleFlight.RedisSentinel]
298+
# Endpoints is the redis sentinel endpoints to discover a redis
299+
# master for a SingleFlight lock.
300+
# Env override: ATHENS_REDIS_SENTINEL_ENDPOINTS
301+
Endpoints = ["127.0.0.1:26379"]
302+
# MasterName is the redis sentinel master name to use to discover
303+
# the master for a SingleFlight lock
304+
MasterName = "redis-1"
305+
# SentinelPassword is an optional password for authenticating with
306+
# redis sentinel
307+
SentinelPassword = "sekret"
293308

294309
# Password is the password for a redis SingleFlight lock.
295310
# Env override: ATHENS_REDIS_PASSWORD

docker-compose.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ services:
8181
image: redis
8282
ports:
8383
- 6379:6379
84+
redis-sentinel:
85+
image: bitnami/redis-sentinel
86+
environment:
87+
- REDIS_MASTER_HOST=redis
88+
- REDIS_MASTER_SET=redis-1
89+
- REDIS_SENTINEL_PASSWORD=sekret
90+
- REDIS_SENTINEL_QUORUM=1
91+
ports:
92+
- 26379:26379
8493
protectedredis:
8594
image: redis
8695
ports:

docs/content/configuration/storage.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,95 @@ It assumes that you already have the following:
335335
# Name of container in the blob storage
336336
# Env override: ATHENS_AZURE_CONTAINER_NAME
337337
ContainerName = "MY_AZURE_BLOB_CONTAINER_NAME"
338+
339+
## Running multiple Athens pointed at the same storage
340+
341+
Athens has the ability to run concurrently pointed at the same storage medium, using
342+
a distributed locking mechanism called "single flight".
343+
344+
By default, Athens is configured to use the `memory` single flight, which
345+
stores locks in local memory. This works when running a single Athens instance, given
346+
the process has access to it's own memory. However, when running multiple Athens instances
347+
pointed at the same storage, a distributed locking mechansism is required.
348+
349+
Athens supports several distributed locking mechanisms:
350+
351+
- `etcd`
352+
- `redis`
353+
- `redis-sentinel`
354+
- `gcp` (available when using the `gcp` storage type)
355+
- `azureblob` (available when using the `azureblob` storage type)
356+
357+
Setting the `SingleFlightType` (or `ATHENS_SINGLE_FLIGHT TYPE` in the environment) configuration
358+
value will enable usage of one of the above mechanisms. The `azureblob` and `gcp` types require
359+
no extra configuration.
360+
361+
### Using etcd as the single flight mechanism
362+
363+
Using the `etcd` mechanism is very simple, just a comma separated list of etcd endpoints.
364+
The recommend configuration is 3 endpoints, however, more can be used.
365+
366+
SingleFlightType = "etcd"
367+
368+
[SingleFlight]
369+
[SingleFlight.Etcd]
370+
# Env override: ATHENS_ETCD_ENDPOINTS
371+
Endpoints = "localhost:2379,localhost:22379,localhost:32379"
372+
373+
### Using redis as the single flight mechanism
374+
375+
Athens supports two mechanisms of communicating with redis: direct connection, and
376+
connecting via redis sentinels.
377+
378+
#### Direct connection to redis
379+
380+
Using a direct connection to redis is simple, and only requires a single `redis-server`.
381+
You can also optionally specify a password to connect to the redis server with
382+
383+
SingleFlightType = "redis"
384+
385+
[SingleFlight]
386+
[SingleFlight.Redis]
387+
# Endpoint is the redis endpoint for the single flight mechanism
388+
# Env override: ATHENS_REDIS_ENDPOINT
389+
Endpoint = "127.0.0.1:6379"
390+
391+
# Password is the password for the redis instance
392+
# Env override: ATHENS_REDIS_PASSWORD
393+
Password = ""
394+
395+
#### Connecting to redis via redis sentinel
396+
397+
**NOTE**: redis-sentinel requires a working knowledge of redis and is not recommended for
398+
everyone.
399+
400+
redis sentinel is a high-availability set up for redis, it provides automated monitoring, replication,
401+
failover and configuration of multiple redis servers in a leader-follower setup. It is more
402+
complex than running a single redis server and requires multiple disperate instances of redis
403+
running distributed across nodes.
404+
405+
For more details on redis-sentinel, check out the [documentation](https://redis.io/topics/sentinel)
406+
407+
As redis-sentinel is a more complex set up of redis, it requires more configuration than standard redis.
408+
409+
Required configuration:
410+
411+
- `Endpoints` is a list of redis-sentinel endpoints to connect to, typically 3, but more can be used
412+
- `MasterName` is the named master instance, as configured in the `redis-sentinel` [configuration](https://redis.io/topics/sentinel#configuring-sentinel)
413+
414+
Optionally, like `redis`, you can also specify a password to connect to the `redis-sentinel` endpoints with
415+
416+
SingleFlightType = "redis-sentinel"
417+
418+
[SingleFlight]
419+
[SingleFlight.RedisSentinel]
420+
# Endpoints is the redis sentinel endpoints to discover a redis
421+
# master for a SingleFlight lock.
422+
# Env override: ATHENS_REDIS_SENTINEL_ENDPOINTS
423+
Endpoints = ["127.0.0.1:26379"]
424+
# MasterName is the redis sentinel master name to use to discover
425+
# the master for a SingleFlight lock
426+
MasterName = "redis-1"
427+
# SentinelPassword is an optional password for authenticating with
428+
# redis sentinel
429+
SentinelPassword = "sekret"

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ require (
1414
github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20180917103902-e6c7f767dc57
1515
github.com/aws/aws-sdk-go v1.15.24
1616
github.com/bsm/redis-lock v8.0.0+incompatible
17+
github.com/bsm/redislock v0.4.2
1718
github.com/codegangsta/negroni v1.0.0 // indirect
1819
github.com/fatih/color v1.7.0
1920
github.com/go-playground/locales v0.12.1 // indirect
2021
github.com/go-playground/universal-translator v0.16.0 // indirect
2122
github.com/go-redis/redis v6.15.2+incompatible
23+
github.com/go-redis/redis/v7 v7.2.0
2224
github.com/gobuffalo/envy v1.6.7
2325
github.com/gobuffalo/httptest v1.0.4
2426
github.com/golang/snappy v0.0.1 // indirect

go.sum

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
5454
github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k=
5555
github.com/bsm/redis-lock v8.0.0+incompatible h1:QgB0J2pNG8hUfndTIvpPh38F5XsUTTvO7x8Sls++9Mk=
5656
github.com/bsm/redis-lock v8.0.0+incompatible/go.mod h1:8dGkQ5GimBCahwF2R67tqGCJbyDZSp0gzO7wq3pDrik=
57+
github.com/bsm/redislock v0.4.2 h1:+7WydoauDwf5Qw0ajaI/g3t26dQ/ovGU0Dv59sVvQzc=
58+
github.com/bsm/redislock v0.4.2/go.mod h1:zeuSDdDFtEDtbAgKsw7NDucfSVR0zLWBv8tMpro/6UM=
5759
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
5860
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=
5961
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
@@ -90,6 +92,10 @@ github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rm
9092
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
9193
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
9294
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
95+
github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
96+
github.com/go-redis/redis/v7 v7.0.0-beta.4/go.mod h1:xhhSbUMTsleRPur+Vgx9sUHtyN33bdjxY+9/0n9Ig8s=
97+
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
98+
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
9399
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
94100
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
95101
github.com/go-test/deep v1.0.1 h1:UQhStjbkDClarlmv0am7OXXO4/GaPdCGiUiMTvi28sg=
@@ -111,6 +117,8 @@ github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
111117
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
112118
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
113119
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
120+
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
121+
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
114122
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
115123
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
116124
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -209,9 +217,15 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
209217
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
210218
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
211219
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
220+
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
221+
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
222+
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
212223
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
213224
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
214225
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
226+
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
227+
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
228+
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
215229
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
216230
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
217231
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
@@ -333,6 +347,8 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn
333347
golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
334348
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
335349
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
350+
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
351+
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
336352
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
337353
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
338354
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -353,6 +369,8 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
353369
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
354370
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dzugGxJ/SQHoNufZJq1w=
355371
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
372+
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
373+
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
356374
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
357375
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
358376
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -388,6 +406,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
388406
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
389407
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
390408
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
409+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
391410
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
392411
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
393412
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -403,6 +422,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
403422
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
404423
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
405424
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
425+
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
426+
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
406427
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
407428
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
408429
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=

pkg/config/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ func defaultConfig() *Config {
164164
SingleFlight: &SingleFlight{
165165
Etcd: &Etcd{"localhost:2379,localhost:22379,localhost:32379"},
166166
Redis: &Redis{"127.0.0.1:6379", ""},
167+
RedisSentinel: &RedisSentinel{
168+
Endpoints: []string{"127.0.0.1:26379"},
169+
MasterName: "redis-1",
170+
SentinelPassword: "sekret",
171+
},
167172
},
168173
}
169174
}

pkg/config/singleflight.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ package config
44
// backend configurations for a distributed
55
// lock or single flight mechanism.
66
type SingleFlight struct {
7-
Etcd *Etcd
8-
Redis *Redis
7+
Etcd *Etcd
8+
Redis *Redis
9+
RedisSentinel *RedisSentinel
910
}
1011

1112
// Etcd holds client side configuration
@@ -21,3 +22,11 @@ type Redis struct {
2122
Endpoint string `envconfig:"ATHENS_REDIS_ENDPOINT"`
2223
Password string `envconfig:"ATHENS_REDIS_PASSWORD"`
2324
}
25+
26+
// RedisSentinel is the configuration for using redis with sentinel
27+
// for SingleFlight
28+
type RedisSentinel struct {
29+
Endpoints []string `envconfig:"ATHENS_REDIS_SENTINEL_ENDPOINTS"`
30+
MasterName string `envconfig:"ATHENS_REDIS_SENTINEL_MASTER_NAME"`
31+
SentinelPassword string `envconfig:"ATHENS_REDIS_SENTINEL_PASSWORD"`
32+
}

pkg/stash/with_redis.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"context"
55
"time"
66

7-
lock "github.com/bsm/redis-lock"
8-
"github.com/go-redis/redis"
7+
lock "github.com/bsm/redislock"
8+
"github.com/go-redis/redis/v7"
99
"github.com/gomods/athens/pkg/config"
1010
"github.com/gomods/athens/pkg/errors"
1111
"github.com/gomods/athens/pkg/observ"
@@ -44,17 +44,15 @@ func (s *redisLock) Stash(ctx context.Context, mod, ver string) (newVer string,
4444
mv := config.FmtModVer(mod, ver)
4545

4646
// Obtain a new lock with default settings
47-
lock, err := lock.Obtain(s.client, mv, &lock.Options{
48-
LockTimeout: time.Minute * 5,
49-
RetryCount: 60 * 5,
50-
RetryDelay: time.Second,
47+
lock, err := lock.Obtain(s.client, mv, time.Minute*5, &lock.Options{
48+
RetryStrategy: lock.LimitRetry(lock.LinearBackoff(time.Second), 60*5),
5149
})
5250
if err != nil {
5351
return ver, errors.E(op, err)
5452
}
5553
defer func() {
56-
const op errors.Op = "redis.Unlock"
57-
lockErr := lock.Unlock()
54+
const op errors.Op = "redis.Release"
55+
lockErr := lock.Release()
5856
if err == nil && lockErr != nil {
5957
err = errors.E(op, lockErr)
6058
}

0 commit comments

Comments
 (0)