pg_advisory_locker 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ bundler_args: --without staging development deploy
5
+ before_install:
6
+ before_script: cp spec/dummy/config/database-sample.yml spec/dummy/config/database.yml; cd spec/dummy; bundle exec rake db:create;
7
+ script: rspec spec
8
+ branches:
9
+ only:
10
+ - master
11
+ - production
12
+ notifications:
13
+ email:
14
+ - dev-fma@fiksu.com
15
+
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2012, Fiksu, Inc.
1
+ Copyright (c) 2010-2013, Fiksu, Inc.
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ pg_advisory_locker
2
+ ==================
3
+
4
+ Helper for calling PostgreSQL functions: pg_advisory_lock,
5
+ pg_advisory_try_lock, and pg_advisory_unlock.
6
+
7
+ Examples
8
+ ========
9
+
10
+ Basic example of passing a block to the locker
11
+
12
+ ```
13
+ class Foo < ActiveRecord::Base
14
+ include PgAdvisoryLocker
15
+
16
+ def self.lock_for_whatever(&block)
17
+ return lock_record(0, &block)
18
+ end
19
+
20
+ def self.do_something
21
+ lock_for_whatever do
22
+ # do something here
23
+ end
24
+ end
25
+ end
26
+ ```
27
+
28
+ Advisory lock on id:
29
+
30
+ ```
31
+ class Foo < ActiveRecord::Base
32
+ include PgAdvisoryLocker
33
+
34
+ def lock_for_whatever
35
+ return advisory_lock
36
+ end
37
+
38
+ def unlock_for_whatever
39
+ return advisory_unlock
40
+ end
41
+
42
+ def do_something
43
+ lock_for_whatever
44
+ begin
45
+ # do something
46
+ ensure
47
+ unlock_for_whatever
48
+ end
49
+ end
50
+ end
51
+ ```
52
+ Generic locking:
53
+ ```
54
+ class Foo < ActiveRecord::Base
55
+ include PgAdvisoryLocker
56
+ end
57
+
58
+ Foo.pg_advisory_lock(0, 0) do
59
+ # do something
60
+ end
61
+ ```
@@ -3,19 +3,40 @@ module PgAdvisoryLocker
3
3
  base.extend(ClassMethods)
4
4
  end
5
5
 
6
+ # advisory lock this row associated identified by model#id
7
+ #
8
+ # blocks until advisory lock is release
9
+ # acquires lock on return
10
+ #
11
+ # if block is passed in, lock/unlock around the block
6
12
  def advisory_lock(&block)
7
13
  return self.class.lock_record(id, &block)
8
14
  end
9
15
 
16
+ # advisory try lock this row associated identified by model#id
17
+ #
18
+ # if lock is acquired, acquires lock and returns true
19
+ # if lock is currently acquired, returns false
20
+ # never blocks
21
+ #
22
+ # if block is passed in, lock/unlock around the block
23
+ # executing block only if lock is acquired
10
24
  def advisory_try_lock(&block)
11
25
  return self.class.try_lock_record(id, &block)
12
26
  end
13
27
 
28
+ # advisory unlock this row associated identified by model#id
29
+ #
30
+ # on return releases lock
14
31
  def advisory_unlock
15
32
  self.class.unlock_record(id)
16
33
  end
17
34
 
18
35
  module ClassMethods
36
+ # table_oid is good unique identifier value for the table
37
+ # We could use a has of the name if the thought there would
38
+ # be no collisions
39
+ # The OID is always unique, so we use it
19
40
  def table_oid
20
41
  if @table_oid.nil?
21
42
  sql_table_components = table_name.split('.')
@@ -37,39 +58,85 @@ module PgAdvisoryLocker
37
58
  return @table_oid
38
59
  end
39
60
 
40
- def lock_record(id, &block)
61
+ # advisory lock for this model, with key2 as argument
62
+ # blocks until advisory lock is release
63
+ # acquires lock on return
64
+ #
65
+ # if block is passed in, lock/unlock around the block
66
+ def lock_record(key2, &block)
67
+ return pg_advisory_lock(table_oid, key2, &block)
68
+ end
69
+
70
+ # advisory try lock for this model, with key2 as argument
71
+ #
72
+ # if lock is acquired, acquires lock and returns true
73
+ # if lock is currently acquired, returns false
74
+ # never blocks
75
+ #
76
+ # if block is passed in, lock/unlock around the block
77
+ # executing block only if lock is acquired
78
+ def try_lock_record(key2, &block)
79
+ return pg_try_advisory_lock(table_oid, key2, &block)
80
+ end
81
+
82
+ # advisory unlock for this model, with key2 as argument
83
+ # on return releases lock
84
+ def unlock_record(key2)
85
+ return pg_advisory_unlock(table_oid, key2)
86
+ end
87
+
88
+ # pg_advisory_lock - direct access to postgres pg_advisory_lock function
89
+ # key1: int
90
+ # key2: int
91
+ # if block is passed in, lock/unlock around the block
92
+ def pg_advisory_lock(key1, key2, &block)
41
93
  locked = uncached do
42
- find_by_sql(["select pg_advisory_lock(?, ?)", table_oid, id])[0].pg_advisory_lock == "t"
94
+ find_by_sql(["select pg_advisory_lock(?, ?)", key1, key2]).first.pg_advisory_lock == "t"
43
95
  end
44
96
  if block.present?
45
97
  begin
46
98
  return block.call
47
99
  ensure
48
- unlock_record(id)
100
+ pg_advisory_unlock(key1, key2)
49
101
  end
50
102
  end
51
103
  return locked
52
104
  end
53
105
 
54
- def try_lock_record(id, &block)
106
+ # pg_try_advisory_lock - direct access to postgres pg_try_advisory_lock function
107
+ # key1: int
108
+ # key2: int
109
+ #
110
+ # if lock is acquired, acquires lock and returns true
111
+ # if lock is currently acquired, returns false
112
+ # never blocks
113
+ #
114
+ # if block is passed in, lock/unlock around the block
115
+ # executing block only if lock is acquired
116
+ def pg_try_advisory_lock(key1, key2, &block)
55
117
  locked = uncached do
56
- find_by_sql(["select pg_try_advisory_lock(?, ?)", table_oid, id])[0].pg_try_advisory_lock == "t"
118
+ find_by_sql(["select pg_try_advisory_lock(?, ?)", key1, key2]).first.pg_try_advisory_lock == "t"
57
119
  end
58
120
  if locked
59
121
  if block.present?
60
122
  begin
61
123
  block.call
62
124
  ensure
63
- unlock_record(id)
125
+ pg_advisory_unlock(key1, key2)
64
126
  end
65
127
  end
66
128
  end
67
129
  return locked
68
130
  end
69
131
 
70
- def unlock_record(id)
132
+ # pg_advisory_unlock - direct access to postgres pg_advisory_unlock function
133
+ # key1: int
134
+ # key2: int
135
+ #
136
+ # on return releases lock
137
+ def pg_advisory_unlock(key1, key2)
71
138
  unlocked = uncached do
72
- find_by_sql(["select pg_advisory_unlock(?, ?)", table_oid, id])[0].pg_advisory_unlock == "t"
139
+ find_by_sql(["select pg_advisory_unlock(?, ?)", key1, key2]).first.pg_advisory_unlock == "t"
73
140
  end
74
141
  return unlocked
75
142
  end
@@ -1,4 +1,4 @@
1
1
  module PgAdvisoryLocker
2
2
  # the current version of this gem
3
- VERSION = "1.0.2"
3
+ VERSION = "1.1.0"
4
4
  end
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.name = 'pg_advisory_locker'
8
8
  s.version = PgAdvisoryLocker::VERSION
9
9
  s.license = 'New BSD License'
10
- s.date = '2012-10-02'
10
+ s.date = '2013-04-26'
11
11
  s.summary = "Helper for calling PostgreSQL pg_advisory_lock, pg_advisory_try_lock, and pg_advisory_unlock."
12
12
  s.description = "This gem provides a module that, when included in your ActiveRecord model, provides methods to acquire and release advisory locks for PostgreSQL connections."
13
13
  s.authors = ["Keith Gabryelski"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_advisory_locker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-02 00:00:00.000000000 Z
12
+ date: 2013-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pg
@@ -68,10 +68,11 @@ extra_rdoc_files: []
68
68
  files:
69
69
  - .gitignore
70
70
  - .rspec
71
+ - .travis.yml
71
72
  - Gemfile
72
73
  - Gemfile.lock
73
74
  - LICENSE
74
- - README
75
+ - README.md
75
76
  - Rakefile
76
77
  - lib/pg_advisory_locker.rb
77
78
  - lib/pg_advisory_locker/pg_advisory_locker.rb
data/README DELETED
@@ -1,47 +0,0 @@
1
- pg_advisory_locker
2
- ==================
3
-
4
- Helper for calling PostgreSQL functions: pg_advisory_lock,
5
- pg_advisory_try_lock, and pg_advisory_unlock.
6
-
7
- Examples
8
- ========
9
-
10
- Basic example of passing a block to the locker
11
-
12
- class Foo < ActiveRecord::Base
13
- include PgAdvisoryLocker
14
-
15
- def self.lock_for_whatever(&block)
16
- return lock_record(0, &block)
17
- end
18
-
19
- def self.do_something
20
- lock_for_whatever do
21
- # do something here
22
- end
23
- end
24
- end
25
-
26
- Advisory lock on id:
27
-
28
- class Foo < ActiveRecord::Base
29
- include PgAdvisoryLocker
30
-
31
- def lock_for_whatever
32
- return advisory_lock
33
- end
34
-
35
- def unlock_for_whatever
36
- return advisory_unlock
37
- end
38
-
39
- def do_something
40
- lock_for_whatever
41
- begin
42
- # do something
43
- ensure
44
- unlock_for_whatever
45
- end
46
- end
47
- end