UNPKG

1.32 kBtext/coffeescriptView Raw
1
2_ = require('lodash')
3
4defaults = {
5 client: null
6 prefix: 'redlocks:'
7 timeout: 60
8 retries: 2
9}
10
11RELEASE_LUA = """
12 if redis.call("get",KEYS[1]) == ARGV[1] then
13 return redis.call("del",KEYS[1])
14 else
15 return 0
16 end
17"""
18
19KEEPALIVE_LUA = """
20 if redis.call("get",KEYS[1]) == ARGV[1] then
21 return redis.call("expire",ARGV[2])
22 else
23 return 0
24 end
25"""
26
27redlock = (opts) ->
28
29 opts = _.merge(defaults, opts)
30
31 unless opts.client?
32 throw new Error("You must provide a Redis client to redlock")
33
34 return (name, timeout, callback) ->
35 unless callback?
36 callback = timeout
37 timeout = opts.timeout
38 unless callback?
39 callback = _.noop
40 }
41
42 lockId = opts.prefix + name
43 token = "#{Date.now()}-#{(Math.random() + 1).toString(36).substr(2, 9)}"
44
45 lock = {
46 release: (callback) ->
47 callback ?= _.noop
48 opts.client.eval([RELEASE_LUA, 1, lockId, token], callback)
49 }
50 keepAlive: (callback) ->
51 callback ?= _.noop
52 opts.client.eval([KEEPALIVE_LUA, 1, lockId, token, timeout], callback)
53 }
54 }
55
56 opts.client.set([lockId, token, 'NX', 'EX', timeout], (err, value) ->
57 if err
58 return callback(err)
59
60 if value
61 callback(null, lock)
62 else
63 callback()
64 )
65
66module.exports = redlock