pg_advisory_locker 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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