lock-smith 0.0.9 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/locksmith/config.rb +5 -0
- data/lib/locksmith/dynamodb.rb +16 -7
- data/lib/locksmith/pg.rb +35 -18
- data/readme.md +5 -13
- metadata +1 -2
data/lib/locksmith/config.rb
CHANGED
data/lib/locksmith/dynamodb.rb
CHANGED
@@ -9,8 +9,6 @@ module Locksmith
|
|
9
9
|
@dynamo_lock = Mutex.new
|
10
10
|
@table_lock = Mutex.new
|
11
11
|
|
12
|
-
LOCK_TABLE = "Locks"
|
13
|
-
|
14
12
|
def lock(name, opts={})
|
15
13
|
opts[:ttl] ||= 60
|
16
14
|
opts[:attempts] ||= 3
|
@@ -50,17 +48,20 @@ module Locksmith
|
|
50
48
|
end
|
51
49
|
|
52
50
|
def locks
|
53
|
-
table(
|
51
|
+
table(lock_table)
|
54
52
|
end
|
55
53
|
|
56
54
|
def table(name)
|
57
|
-
|
55
|
+
unless tables[name]
|
56
|
+
@table_lock.synchronize do
|
57
|
+
tables[name] = dynamo.tables[name].load_schema
|
58
|
+
end
|
59
|
+
end
|
60
|
+
tables[name].items
|
58
61
|
end
|
59
62
|
|
60
63
|
def tables
|
61
|
-
@tables ||=
|
62
|
-
map {|t| t.load_schema}.
|
63
|
-
reduce({}) {|h, t| h[t.name] = t; h}
|
64
|
+
@tables ||= {}
|
64
65
|
end
|
65
66
|
|
66
67
|
def dynamo
|
@@ -70,5 +71,13 @@ module Locksmith
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
74
|
+
def lock_table
|
75
|
+
@lock_table
|
76
|
+
end
|
77
|
+
|
78
|
+
def lock_table=(table_name)
|
79
|
+
@lock_table = table_name
|
80
|
+
end
|
81
|
+
|
73
82
|
end
|
74
83
|
end
|
data/lib/locksmith/pg.rb
CHANGED
@@ -1,31 +1,49 @@
|
|
1
1
|
require 'zlib'
|
2
2
|
require 'uri'
|
3
|
+
require 'timeout'
|
4
|
+
require 'locksmith/config'
|
5
|
+
|
3
6
|
module Locksmith
|
4
7
|
module Pg
|
5
|
-
|
6
|
-
BACKOFF = 0.5
|
8
|
+
extend self
|
7
9
|
|
8
|
-
def lock(name)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def lock(name, opts={})
|
11
|
+
opts[:ttl] ||= 60
|
12
|
+
opts[:attempts] ||= 3
|
13
|
+
opts[:lspace] ||= (Config.pg_lock_space || -2147483648)
|
14
|
+
|
15
|
+
if create(name, opts)
|
16
|
+
begin Timeout::timeout(opts[:ttl]) {return(yield)}
|
17
|
+
ensure delete(name, opts)
|
15
18
|
end
|
16
|
-
return result
|
17
|
-
ensure
|
18
|
-
release_lock(i)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
22
|
+
def key(name)
|
23
|
+
i = Zlib.crc32(name)
|
24
|
+
# We need to wrap the value for postgres
|
25
|
+
if i > 2147483647
|
26
|
+
-(-(i) & 0xffffffff)
|
27
|
+
else
|
28
|
+
i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create(name, opts)
|
33
|
+
lock_args = [opts[:lspace], key(name)]
|
34
|
+
opts[:attempts].times.each do |i|
|
35
|
+
res = conn.exec("select pg_try_advisory_lock($1,$2)", lock_args)
|
36
|
+
if res[0]["pg_try_advisory_lock"] == "t"
|
37
|
+
return(true)
|
38
|
+
else
|
39
|
+
return(false) if i == (opts[:attempts] - 1)
|
40
|
+
end
|
41
|
+
end
|
25
42
|
end
|
26
43
|
|
27
|
-
def
|
28
|
-
|
44
|
+
def delete(name, opts)
|
45
|
+
lock_args = [opts[:lspace], key(name)]
|
46
|
+
conn.exec("select pg_advisory_unlock($1,$2)", lock_args)
|
29
47
|
end
|
30
48
|
|
31
49
|
def conn=(conn)
|
@@ -53,4 +71,3 @@ module Locksmith
|
|
53
71
|
|
54
72
|
end
|
55
73
|
end
|
56
|
-
|
data/readme.md
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
**This software is beta quality. Check back later for production quality.**
|
1
|
+
# lock-smith
|
4
2
|
|
5
3
|
A library of locking algorithms for a variety of data stores. Supported Data Stores:
|
6
4
|
|
7
5
|
* DynamoDB
|
8
6
|
* PostgreSQL
|
9
|
-
* TODO: Doozerd
|
10
|
-
* TODO: Zookeeper
|
11
7
|
|
12
8
|
## Usage
|
13
9
|
|
@@ -58,20 +54,16 @@ Locksmith::Pg.lock("my-resource") do
|
|
58
54
|
end
|
59
55
|
```
|
60
56
|
|
61
|
-
|
57
|
+
#### Options
|
62
58
|
|
63
|
-
|
64
|
-
|
59
|
+
* lspace - This defines which lock space lock-smith will use. This is handy if you have multiple applications using advisory locks.
|
60
|
+
* ttl - Wraps your block in a timeout. Be sure to handle `Timeout::Error`.
|
61
|
+
* attempts - Number of attempts to try advisory lock. Your code will only run once.
|
65
62
|
|
66
63
|
## Hacking on Locksmith
|
67
64
|
|
68
65
|
There are still some Data Stores to implement, follow the pattern for PostgreSQLand DynamoDB and submit a pull request.
|
69
66
|
|
70
|
-
## Contributors
|
71
|
-
|
72
|
-
* Ryan Smith
|
73
|
-
* Blake Gentry
|
74
|
-
|
75
67
|
## License
|
76
68
|
|
77
69
|
Copyright (C) 2012 Ryan Smith
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lock-smith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -48,4 +48,3 @@ signing_key:
|
|
48
48
|
specification_version: 3
|
49
49
|
summary: Locking is hard. Write it once.
|
50
50
|
test_files: []
|
51
|
-
has_rdoc:
|