activerecord-batch_touching 1.0.pre.rc1 → 1.2

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: 06aa6d889559fed96fed448ffb100324496a79d1e97e147607067f1a3275ab92
4
- data.tar.gz: 5a737bed02b7812f0feba746bf2ea19bfece091959bdaa25a465dae634b1c38c
3
+ metadata.gz: 4a79724b8d5920ced2e53071d67a37739bd098a6f66080c60a831d056c1fe4d2
4
+ data.tar.gz: 3ee4356cdc64f37ed0349f2f6e39c648f2013c04762021cb19959b3a9ac89b20
5
5
  SHA512:
6
- metadata.gz: b0add569ae81b020e75b5168b00e550d4f69a67cf8e24e5adbb6f45808339ac0d126f69a59bbd0c8620dd073fc762a9cc98283362f9534f3e20197b95da9dc33
7
- data.tar.gz: 2d23e326e341927fa8196c566b3101f8850f56632ab93bdb9bf6506e87a451f9c6141801e40c2c6f2743e7a9cfacc535c555161d06003467e1bd29fa59c0f673
6
+ metadata.gz: c72e5f701b3573d121c9034f2e5751821b8b129c3411584ada3b6fff0b2e12ac52b717128b257808ce54416588dfea4b3dcc597e2e375fda31b0757cf599d770
7
+ data.tar.gz: 61cf15c6e237c604347af26f37c1033fdb2e895a5ead9e01078b706e73a0642a332795828c7ca81b4e17628bd81dd9385e7e3bfea2005f6b66f012347d07fa74
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Activerecord
4
4
  module BatchTouching
5
- VERSION = "1.0"
5
+ VERSION = "1.2"
6
6
  end
7
7
  end
@@ -22,9 +22,17 @@ module ActiveRecord
22
22
  # Person.first.touch
23
23
  # end
24
24
  def transaction(requires_new: nil, isolation: nil, joinable: true, &block)
25
- super(requires_new: requires_new, isolation: isolation, joinable: joinable) do
25
+ result = super(requires_new: requires_new, isolation: isolation, joinable: joinable) do
26
26
  BatchTouching.start(requires_new: requires_new, &block)
27
27
  end
28
+
29
+ if BatchTouching.should_apply_touches?
30
+ super() do
31
+ BatchTouching.apply_touches
32
+ end
33
+ end
34
+
35
+ result
28
36
  end
29
37
  end
30
38
 
@@ -83,12 +91,12 @@ module ActiveRecord
83
91
  def start(requires_new:)
84
92
  states.push State.new
85
93
  yield.tap do
86
- apply_touches if states.length == 1
94
+ gather_touches if states.length == 1
87
95
  end
88
96
  ensure
89
97
  merge_transactions unless $! && requires_new
90
98
 
91
- # Decrement nesting even if +apply_touches+ raised an error. To ensure the stack of States
99
+ # Decrement nesting even if +gather_touches+ raised an error. To ensure the stack of States
92
100
  # is empty after the top-level transaction exits.
93
101
  states.pop
94
102
  end
@@ -99,8 +107,34 @@ module ActiveRecord
99
107
  states.present? && !disabled?
100
108
  end
101
109
 
110
+ def should_apply_touches?
111
+ batched_touches.present?
112
+ end
113
+
114
+ def apply_touches
115
+ batched_touches&.each do |(klass, columns), records|
116
+ records.reject!(&:destroyed?)
117
+ touch_records klass, columns, records, batched_touches_time
118
+ end
119
+
120
+ reset!
121
+ end
122
+
102
123
  private
103
124
 
125
+ def reset!
126
+ Thread.current[:batch_touching_batch] = nil
127
+ Thread.current[:batch_touching_time] = nil
128
+ end
129
+
130
+ def batched_touches
131
+ Thread.current[:batch_touching_batch]
132
+ end
133
+
134
+ def batched_touches_time
135
+ Thread.current[:batch_touching_time]
136
+ end
137
+
104
138
  def states
105
139
  Thread.current[:batch_touching_states] ||= []
106
140
  end
@@ -115,8 +149,8 @@ module ActiveRecord
115
149
  states[-2].merge!(current_state) if states.length > 1
116
150
  end
117
151
 
118
- # Apply the touches that were batched. We're in a transaction already so there's no need to open one.
119
- def apply_touches
152
+ # Gather all the touches that were batched.
153
+ def gather_touches
120
154
  current_time = ActiveRecord::Base.current_time_from_proper_timezone
121
155
  already_touched = Set.new
122
156
  all_states = State.new
@@ -131,10 +165,10 @@ module ActiveRecord
131
165
 
132
166
  # Sort by class name. Having a consistent order can help mitigate deadlocks.
133
167
  sorted_records = all_states.records.keys.sort_by { |k| k.first.name }.to_h { |k| [k, all_states.records[k]] }
134
- sorted_records.each do |(klass, columns), records|
135
- records.reject!(&:destroyed?)
136
- touch_records klass, columns, records, current_time
137
- end
168
+
169
+ # Save results to a thread so that we can reference these later in their own transaction.
170
+ Thread.current[:batch_touching_batch] = sorted_records
171
+ Thread.current[:batch_touching_time] = current_time
138
172
  end
139
173
 
140
174
  # Perform DB update to touch records
@@ -144,7 +178,8 @@ module ActiveRecord
144
178
  sql = columns.map { |column| "#{klass.connection.quote_column_name(column)} = :time" }.join(", ")
145
179
  sql += ", #{klass.locking_column} = #{klass.locking_column} + 1" if klass.locking_enabled?
146
180
 
147
- klass.unscoped.where(klass.primary_key => records.to_a).update_all([sql, time: time])
181
+ ids = records.map { |record| record.send(klass.primary_key) }.sort
182
+ klass.unscoped.where(klass.primary_key => ids).update_all([sql, time: time])
148
183
  end
149
184
 
150
185
  # Set new timestamp in memory, without updating the DB just yet.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-batch_touching
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.pre.rc1
4
+ version: '1.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Morearty
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-07-03 00:00:00.000000000 Z
12
+ date: 2022-07-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -192,7 +192,7 @@ files:
192
192
  - lib/activerecord/batch_touching.rb
193
193
  - lib/activerecord/batch_touching/state.rb
194
194
  - lib/activerecord/batch_touching/version.rb
195
- homepage: https://github.com/irphilli/activerecord-batch_touching
195
+ homepage: https://github.com/ProductPlan/activerecord-batch_touching
196
196
  licenses:
197
197
  - MIT
198
198
  metadata:
@@ -208,9 +208,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
208
208
  version: 2.7.0
209
209
  required_rubygems_version: !ruby/object:Gem::Requirement
210
210
  requirements:
211
- - - ">"
211
+ - - ">="
212
212
  - !ruby/object:Gem::Version
213
- version: 1.3.1
213
+ version: '0'
214
214
  requirements: []
215
215
  rubygems_version: 3.3.7
216
216
  signing_key: