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.
@@ -14,6 +14,11 @@ module Locksmith
14
14
  !env(key).nil?
15
15
  end
16
16
 
17
+ def pg_lock_space
18
+ n = "LOCKSMITH_PG_LOCK_SPACE"
19
+ env(n) && env(n).to_i
20
+ end
21
+
17
22
  def aws_id
18
23
  @aws_id ||= env!("AWS_ID")
19
24
  end
@@ -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(LOCK_TABLE)
51
+ table(lock_table)
54
52
  end
55
53
 
56
54
  def table(name)
57
- @table_lock.synchronize {tables[name].items}
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 ||= dynamo.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
@@ -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
- extend self
6
- BACKOFF = 0.5
8
+ extend self
7
9
 
8
- def lock(name)
9
- i = Zlib.crc32(name)
10
- result = nil
11
- begin
12
- sleep(BACKOFF) until write_lock(i)
13
- if block_given?
14
- result = yield
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 write_lock(i)
23
- r = conn.exec("select pg_try_advisory_lock($1)", [i])
24
- r[0]["pg_try_advisory_lock"] == "t"
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 release_lock(i)
28
- conn.exec("select pg_advisory_unlock($1)", [i])
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
- # Locksmith
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
- ## Why Locksmith
57
+ #### Options
62
58
 
63
- Locking code is tricky. Ideally, I would write it once, verify in production for
64
- a year then never think about it again.
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.9
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: