pg_advisory_lock 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 466169c01607df8b0c40594fa296e1fed78308d06a5512bab01e12cbafe59c2d
4
- data.tar.gz: 55fb38aafaaad466d4ef287dcb5ae9b2ad17bdd2e22cfc8ddeb6ca75e7d036e4
3
+ metadata.gz: 0f4f49429d7f217072b2927e3f33876f0841caf8d027725bd7981eed010e1a37
4
+ data.tar.gz: 4bd6514b91d8dad257d575b7147a41f8faa5006dd398a7d98d340a2612c0a4f8
5
5
  SHA512:
6
- metadata.gz: cb2a78d382278811c09863faee99aca67c7fffdfb9f579b9ea96f76c3a895888b598c1bbd16c2ea5e57cbd409f6d36d60dc8b185b00c7861a83c3ac98dfe1d75
7
- data.tar.gz: 8fa4803b480af658d61c4c86441e7f0e0886f573a373ab182ed2c3b5bf41f195a9f1e4d81bdecadd1881655feb28eed39b1dd84f0bb8386dfcf2c15033f72fae
6
+ metadata.gz: 92a9005c04a0b898ec8489027bb065ecf713ec75cc83fe0e7d0c721740874463bd80ccad2919a5be780f7b0cc5d6626593b3e5b844e9eb76b1f33851b41a6f9a
7
+ data.tar.gz: 8199402c1fd8ab0b8c72df92698f94912a81bc91a4af64ba2edd9385d68d9dcf3e0439ba72ce23424be5e4db3738eade36ebd2127ee6a2372539452180e5c065
data/README.md CHANGED
@@ -24,8 +24,6 @@ Or install it yourself as:
24
24
  create subclass from `PgAdvisoryLock::Base` and define `model_class` for it
25
25
 
26
26
  ```ruby
27
- require 'pg_sql_caller'
28
-
29
27
  class MySqlCaller < PgAdvisoryLock::Base
30
28
  model_class 'ApplicationRecord'
31
29
  end
@@ -31,6 +31,8 @@ module PgAdvisoryLock
31
31
  self._sql_caller_class = klass
32
32
  end
33
33
 
34
+ # Locks specific advisory lock.
35
+ # If it's already locked just waits.
34
36
  # @param name [Symbol, String] - lock name (will be transformed to number).
35
37
  # @param transaction [Boolean] - if true lock will be released at the end of current transaction
36
38
  # otherwise it will be released at the end of block.
@@ -41,7 +43,23 @@ module PgAdvisoryLock
41
43
  # @raise [ArgumentError] when lock name is invalid.
42
44
  # @return yield
43
45
  def with_lock(name, transaction: true, shared: false, id: nil, &block)
44
- new(name, transaction: transaction, shared: shared, id: id).lock(&block)
46
+ new(name, transaction: transaction, shared: shared, id: id, wait: true).lock(&block)
47
+ end
48
+
49
+ # Tries to lock specific advisory lock.
50
+ # If it's already locked raises exception.
51
+ # @param name [Symbol, String] - lock name (will be transformed to number).
52
+ # @param transaction [Boolean] - if true lock will be released at the end of current transaction
53
+ # otherwise it will be released at the end of block.
54
+ # @param shared [Boolean] - is lock shared or not.
55
+ # @param id [Integer] - number that will be used in pair with lock number to perform advisory lock.
56
+ # @yield - call block when lock is acquired
57
+ # block must be passed if transaction argument is false.
58
+ # @raise [ArgumentError] when lock name is invalid.
59
+ # @raise [PgAdvisoryLock::LockNotObtained] when wait: false passed and lock already locked.
60
+ # @return yield
61
+ def try_lock(name, transaction: true, shared: false, id: nil, &block)
62
+ new(name, transaction: transaction, shared: shared, id: id, wait: false).lock(&block)
45
63
  end
46
64
  end
47
65
 
@@ -50,16 +68,19 @@ module PgAdvisoryLock
50
68
  # otherwise it will be released at the end of block.
51
69
  # @param shared [Boolean] - is lock shared or not.
52
70
  # @param id [Integer] - number that will be used in pair with lock number to perform advisory lock.
53
- def initialize(name, transaction: false, shared: false, id: nil)
71
+ # @param wait [Boolean] - when locked by someone else: true - wait for lock, raise PgAdvisoryLock::LockNotObtained.
72
+ def initialize(name, transaction:, shared:, id:, wait:)
54
73
  @name = name.to_sym
55
74
  @transaction = transaction
56
75
  @shared = shared
57
76
  @id = id
77
+ @wait = wait
58
78
  end
59
79
 
60
80
  # @yield - call block when lock is acquired
61
81
  # block must be passed if transaction argument is false.
62
82
  # @raise [ArgumentError] when lock name is invalid.
83
+ # @raise [PgAdvisoryLock::LockNotObtained] when wait: false passed and lock already locked.
63
84
  # @return yield
64
85
  def lock(&block)
65
86
  with_logger do
@@ -70,7 +91,7 @@ module PgAdvisoryLock
70
91
 
71
92
  private
72
93
 
73
- attr_reader :transaction, :shared, :name, :id
94
+ attr_reader :transaction, :shared, :name, :id, :wait
74
95
 
75
96
  def with_logger
76
97
  return yield if logger.nil? || !logger.respond_to?(:tagged)
@@ -109,9 +130,14 @@ module PgAdvisoryLock
109
130
  end
110
131
 
111
132
  def perform_lock(lock_number)
112
- function_name = "pg_advisory#{'_xact' if transaction}_lock#{'_shared' if shared}"
133
+ function_name = "pg#{'_try' unless wait}_advisory#{'_xact' if transaction}_lock#{'_shared' if shared}"
113
134
 
114
- sql_caller_class.execute("SELECT #{function_name}(#{lock_number})")
135
+ if wait
136
+ sql_caller_class.execute("SELECT #{function_name}(#{lock_number})")
137
+ else
138
+ result = sql_caller_class.select_value("SELECT #{function_name}(#{lock_number})")
139
+ raise LockNotObtained, "#{self.class} can't obtain lock (#{name}, #{id})" unless result
140
+ end
115
141
  end
116
142
 
117
143
  def perform_unlock(lock_number)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgAdvisoryLock
4
+ class LockNotObtained < StandardError
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgAdvisoryLock
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pg_advisory_lock/version'
4
+ require 'pg_advisory_lock/lock_not_obtained'
4
5
  require 'pg_advisory_lock/base'
5
6
 
6
7
  module PgAdvisoryLock
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_advisory_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Talakevich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-25 00:00:00.000000000 Z
11
+ date: 2022-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -72,6 +72,7 @@ files:
72
72
  - bin/setup
73
73
  - lib/pg_advisory_lock.rb
74
74
  - lib/pg_advisory_lock/base.rb
75
+ - lib/pg_advisory_lock/lock_not_obtained.rb
75
76
  - lib/pg_advisory_lock/version.rb
76
77
  - pg_advisory_lock.gemspec
77
78
  homepage: https://github.com/didww/pg_advisory_lock
@@ -96,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
97
  - !ruby/object:Gem::Version
97
98
  version: '0'
98
99
  requirements: []
99
- rubygems_version: 3.0.4
100
+ rubygems_version: 3.1.6
100
101
  signing_key:
101
102
  specification_version: 4
102
103
  summary: Postgresql Advisory Lock for ActiveRecord