prosopite 1.0.0 → 1.0.4
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +30 -4
- data/lib/prosopite/version.rb +1 -1
- data/lib/prosopite.rb +27 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66728f096f4aafd32cf868f6b24ce88daae9d282b21d2c8b95ed0b732a299d2c
|
4
|
+
data.tar.gz: 4259b7a737bc367742efc158d425a57c1e24c435991f3ad4bd57dbd7a6c195d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fc7f6c647ebfcbce614c0ef7c51a2e9a69b6da7090d889e65dd535891c93a33b07e4228f2d877951a26a06f8bd53687567bf86fed2b77f9558b84a0c24eaa4f
|
7
|
+
data.tar.gz: 139a0047ea3aed0f99a0900bf8c2bf235d5fe1723563859c85bd887daae96a8d65c2b21e5f9ad350384de6424c2ef8a3f7ea1df9d66d8bfb33af2009133f0eb4
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -127,11 +127,12 @@ Prosopite auto-detection can be enabled on all controllers:
|
|
127
127
|
```ruby
|
128
128
|
class ApplicationController < ActionController::Base
|
129
129
|
unless Rails.env.production?
|
130
|
-
|
130
|
+
around_action :n_plus_one_detection
|
131
|
+
|
132
|
+
def n_plus_one_detection
|
131
133
|
Prosopite.scan
|
132
|
-
|
133
|
-
|
134
|
-
after_action do
|
134
|
+
yield
|
135
|
+
ensure
|
135
136
|
Prosopite.finish
|
136
137
|
end
|
137
138
|
end
|
@@ -194,6 +195,31 @@ Prosopite.scan
|
|
194
195
|
Prosopite.finish
|
195
196
|
```
|
196
197
|
|
198
|
+
or
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
Prosopite.scan do
|
202
|
+
<code to scan>
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
206
|
+
## Pausing and resuming scans
|
207
|
+
|
208
|
+
Scans can be paused:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
Prosopite.scan
|
212
|
+
# <code to scan>
|
213
|
+
Prosopite.pause
|
214
|
+
# <code that has n+1s>
|
215
|
+
Prosopite.resume
|
216
|
+
# <code to scan>
|
217
|
+
Prosopite.finish
|
218
|
+
```
|
219
|
+
|
220
|
+
An example of when you might use this is if you are [testing Active Jobs inline](https://guides.rubyonrails.org/testing.html#testing-jobs),
|
221
|
+
and don't want to run Prosopite on background job code, just foreground app code. In that case you could write an [Active Job callback](https://edgeguides.rubyonrails.org/active_job_basics.html#callbacks) that pauses the scan while the job is running.
|
222
|
+
|
197
223
|
## Contributing
|
198
224
|
|
199
225
|
Bug reports and pull requests are welcome on GitHub at https://github.com/charkost/prosopite.
|
data/lib/prosopite/version.rb
CHANGED
data/lib/prosopite.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
|
2
2
|
module Prosopite
|
3
|
+
DEFAULT_ALLOW_LIST = %w(active_record/associations/preloader active_record/validations/uniqueness)
|
4
|
+
|
3
5
|
class NPlusOneQueriesError < StandardError; end
|
4
6
|
class << self
|
5
7
|
attr_writer :raise,
|
@@ -21,12 +23,29 @@ module Prosopite
|
|
21
23
|
@allow_list ||= []
|
22
24
|
|
23
25
|
tc[:prosopite_scan] = true
|
26
|
+
|
27
|
+
if block_given?
|
28
|
+
begin
|
29
|
+
yield
|
30
|
+
finish
|
31
|
+
ensure
|
32
|
+
tc[:prosopite_scan] = false
|
33
|
+
end
|
34
|
+
end
|
24
35
|
end
|
25
36
|
|
26
37
|
def tc
|
27
38
|
Thread.current
|
28
39
|
end
|
29
40
|
|
41
|
+
def pause
|
42
|
+
tc[:prosopite_scan] = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def resume
|
46
|
+
tc[:prosopite_scan] = true
|
47
|
+
end
|
48
|
+
|
30
49
|
def scan?
|
31
50
|
tc[:prosopite_scan]
|
32
51
|
end
|
@@ -53,14 +72,14 @@ module Prosopite
|
|
53
72
|
end
|
54
73
|
end
|
55
74
|
|
75
|
+
next unless fingerprints.uniq.size == 1
|
76
|
+
|
56
77
|
kaller = tc[:prosopite_query_caller][location_key]
|
57
78
|
|
58
|
-
|
79
|
+
is_allowed = kaller.any? { |f| @allow_list.concat(DEFAULT_ALLOW_LIST).any? { |s| f.include?(s) } }
|
80
|
+
unless is_allowed
|
59
81
|
queries = tc[:prosopite_query_holder][location_key]
|
60
|
-
|
61
|
-
unless kaller.any? { |f| f.include?('active_record/validations/uniqueness') }
|
62
|
-
tc[:prosopite_notifications][queries] = kaller
|
63
|
-
end
|
82
|
+
tc[:prosopite_notifications][queries] = kaller
|
64
83
|
end
|
65
84
|
end
|
66
85
|
end
|
@@ -105,7 +124,7 @@ module Prosopite
|
|
105
124
|
|
106
125
|
query.gsub!(/\btrue\b|\bfalse\b/i, "?")
|
107
126
|
|
108
|
-
query.gsub!(/[0-9+-][0-9a-f.
|
127
|
+
query.gsub!(/[0-9+-][0-9a-f.x+-]*/, "?")
|
109
128
|
query.gsub!(/[xb.+-]\?/, "?")
|
110
129
|
|
111
130
|
query.strip!
|
@@ -166,9 +185,9 @@ module Prosopite
|
|
166
185
|
return if @subscribed
|
167
186
|
|
168
187
|
ActiveSupport::Notifications.subscribe 'sql.active_record' do |_, _, _, _, data|
|
169
|
-
sql = data[:sql]
|
188
|
+
sql, name = data[:sql], data[:name]
|
170
189
|
|
171
|
-
if scan? && sql.include?('SELECT') && data[:cached].nil?
|
190
|
+
if scan? && name != "SCHEMA" && sql.include?('SELECT') && data[:cached].nil?
|
172
191
|
location_key = Digest::SHA1.hexdigest(caller.join)
|
173
192
|
|
174
193
|
tc[:prosopite_query_counter][location_key] += 1
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prosopite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mpampis Kostas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|