activerecord-batch_touching 1.0 → 1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a36257abfcfe62c1741375666ac2739ba1acd362bc508b42cd9d7708db0bd81
4
- data.tar.gz: 2a03c834b458618170111c06eec6e063f69c43f011ce691922107857b12e18ec
3
+ metadata.gz: f994be54523c59f7878cbcf822ca03552bb3a365215cb3de7f23c05541381c75
4
+ data.tar.gz: aeab5dbe2bebca4b0b88d2a77ce033b7a288969fe6bddb18c74e332ec729a6bf
5
5
  SHA512:
6
- metadata.gz: 6a8e13e88052d2dc02b2fd087cd4f9df734f7968429309e2c998530c111c7fd37a5220f7aa88c73eca193fd7d861e3806b157305495206863b1534490f9b68f4
7
- data.tar.gz: 1970e2b0152a0d02d0535608a87f74bf884412cd26aaf2bee13905cf4d20b2ffb9ba1c8029ad402420ce8d235f9856a690f45348f3aa87190f81fa318255fadc
6
+ metadata.gz: '0808dfbb8f5ea2fedbd51feaf8c453f9224699017d5c33c54a8c08ff02396b52524b67691937ba9b48b838f84257abf0eab3280500bb976945b7eec7302fc89a'
7
+ data.tar.gz: 4237add83e7f90d3c6852f3221daa31e798eedc2a2b780193e2eab71ae8d17c831c8d2076d899bfed1e84cf830285d501d820fd34ca942223e0f7b53dc5876f2
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Activerecord
4
4
  module BatchTouching
5
- VERSION = "1.0"
5
+ VERSION = "1.1"
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
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'
4
+ version: '1.1'
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-06 00:00:00.000000000 Z
12
+ date: 2022-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord