pgtk 0.32.6 → 0.32.7
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/README.md +12 -0
- data/lib/pgtk/impatient.rb +19 -3
- data/lib/pgtk/pool.rb +23 -0
- data/lib/pgtk/spy.rb +11 -0
- data/lib/pgtk/stash.rb +10 -0
- data/lib/pgtk/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 54a200f1f191d63b73c0137b1a1ace4aa34667f041d141365b47d9c90d96f191
|
|
4
|
+
data.tar.gz: 1518e5031b71a69e3955cabe77397d05917398fb87a12b94ee5c3aa57ab107eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 28bbce0d3b2cfcbe2347f376738938e0e714f22b89fd2696052c56ecf7be83c242e9f0a87c76c235f109ec2008a45a1471ea157fc78f3ac9a8b8b71641ac2556
|
|
7
|
+
data.tar.gz: e94795ee7e4de524c77b5fddefb7a0d2ea9e85ec05beb09ebf81000919afec9a7b54d8a0fb480d9e24c16990fed7b7b142769caefddaefdd32d504f8086f5f46
|
data/README.md
CHANGED
|
@@ -243,6 +243,18 @@ You can exclude specific queries from timeout enforcement using regex patterns:
|
|
|
243
243
|
impatient = Pgtk::Impatient.new(pool, 2, /^SELECT/, /^VACUUM/)
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
+
Excluded queries are never wrapped in a transaction, because statements such as
|
|
247
|
+
`VACUUM`, `REINDEX`, or `CREATE INDEX CONCURRENTLY` cannot run inside a
|
|
248
|
+
transaction block. Instead, a longer fallback timeout (300 seconds by default,
|
|
249
|
+
configurable via the `default:` argument) is applied at the session level with
|
|
250
|
+
`SET statement_timeout` before the query runs, and reset afterwards. Pass
|
|
251
|
+
`default: 0` to run excluded queries with no timeout at all:
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
# Give excluded queries a 60-second fallback timeout
|
|
255
|
+
impatient = Pgtk::Impatient.new(pool, 2, /^VACUUM/, default: 60)
|
|
256
|
+
```
|
|
257
|
+
|
|
246
258
|
The timeout is enforced on the server side: each query is wrapped in a tiny
|
|
247
259
|
transaction that issues `SET LOCAL statement_timeout`, and PostgreSQL itself
|
|
248
260
|
terminates the query at the deadline. This guarantees the server-side
|
data/lib/pgtk/impatient.rb
CHANGED
|
@@ -20,6 +20,14 @@ require_relative '../pgtk'
|
|
|
20
20
|
# transaction-pool PgBouncer that does not forward client disconnects to in-flight
|
|
21
21
|
# server queries). On timeout, +TooSlow+ is raised.
|
|
22
22
|
#
|
|
23
|
+
# Queries that match one of the +off+ regular expressions are excluded from
|
|
24
|
+
# this checking. They are never wrapped in a transaction, because some
|
|
25
|
+
# statements (such as +VACUUM+, +REINDEX+, or +CREATE INDEX CONCURRENTLY+)
|
|
26
|
+
# cannot run inside a transaction block. Instead, a session-level
|
|
27
|
+
# +SET statement_timeout+ is applied on the same connection before the query
|
|
28
|
+
# runs (and reset afterwards), using the +default+ fallback timeout. Pass
|
|
29
|
+
# +default: 0+ to run excluded queries with no timeout at all.
|
|
30
|
+
#
|
|
23
31
|
# Basic usage:
|
|
24
32
|
#
|
|
25
33
|
# # Create and configure a regular pool
|
|
@@ -102,6 +110,13 @@ class Pgtk::Impatient
|
|
|
102
110
|
# behind a transaction-pool PgBouncer). When the deadline fires, the
|
|
103
111
|
# underlying +PG::QueryCanceled+ is translated to +TooSlow+.
|
|
104
112
|
#
|
|
113
|
+
# Queries matching one of the +off+ regular expressions bypass this
|
|
114
|
+
# transaction. They run on a single connection without a transaction block,
|
|
115
|
+
# guarded by a session-level +SET statement_timeout+ (the +default+ fallback,
|
|
116
|
+
# reset afterwards) or by no timeout at all when +default+ is zero. This keeps
|
|
117
|
+
# statements that cannot run inside a transaction, such as +VACUUM+ or
|
|
118
|
+
# +REINDEX+, working as expected.
|
|
119
|
+
#
|
|
105
120
|
# @param [String, Array] query The SQL query with params inside (possibly)
|
|
106
121
|
# @param [Array] args List of arguments
|
|
107
122
|
# @return [Array] Result rows
|
|
@@ -110,9 +125,10 @@ class Pgtk::Impatient
|
|
|
110
125
|
sql = query.is_a?(Array) ? query.join(' ') : query
|
|
111
126
|
if @off.any? { |re| re.match?(sql) }
|
|
112
127
|
ms = Integer(@default * 1000)
|
|
113
|
-
return @pool.
|
|
114
|
-
|
|
115
|
-
t.exec(
|
|
128
|
+
return @pool.exec(sql, *args) if ms.zero?
|
|
129
|
+
return @pool.session do |t|
|
|
130
|
+
t.exec("SET statement_timeout = #{ms}")
|
|
131
|
+
t.exec(sql, *args).tap { t.exec('RESET statement_timeout') }
|
|
116
132
|
end
|
|
117
133
|
end
|
|
118
134
|
start = Time.now
|
data/lib/pgtk/pool.rb
CHANGED
|
@@ -214,6 +214,29 @@ class Pgtk::Pool
|
|
|
214
214
|
end
|
|
215
215
|
end
|
|
216
216
|
|
|
217
|
+
# Grab a single connection from the pool and yield an executor bound to it,
|
|
218
|
+
# WITHOUT starting a transaction. Unlike +transaction+, no +START TRANSACTION+
|
|
219
|
+
# is issued, which makes this suitable for statements that PostgreSQL refuses
|
|
220
|
+
# to run inside a transaction block, such as +VACUUM+, +REINDEX+, or
|
|
221
|
+
# +CREATE INDEX CONCURRENTLY+. All statements executed through the yielded
|
|
222
|
+
# object run on the same connection, so a session-level setting (for example
|
|
223
|
+
# +SET statement_timeout+) made earlier in the block stays in effect for the
|
|
224
|
+
# statements that follow:
|
|
225
|
+
#
|
|
226
|
+
# pgsql.session do |s|
|
|
227
|
+
# s.exec('SET statement_timeout = 5000')
|
|
228
|
+
# s.exec('VACUUM book')
|
|
229
|
+
# s.exec('RESET statement_timeout')
|
|
230
|
+
# end
|
|
231
|
+
#
|
|
232
|
+
# @yield [Object] Yields an executor that responds to +exec+
|
|
233
|
+
# @return [Object] Result of the block
|
|
234
|
+
def session
|
|
235
|
+
connect do |c|
|
|
236
|
+
yield(Txn.new(c, @log))
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
217
240
|
private
|
|
218
241
|
|
|
219
242
|
def connect
|
data/lib/pgtk/spy.rb
CHANGED
|
@@ -97,4 +97,15 @@ class Pgtk::Spy
|
|
|
97
97
|
yield(Pgtk::Spy.new(t, &@block))
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
|
+
|
|
101
|
+
# Run statements on a single connection (no transaction) with spying on
|
|
102
|
+
# each SQL query.
|
|
103
|
+
#
|
|
104
|
+
# @yield [Pgtk::Spy] Yields a spy bound to one connection
|
|
105
|
+
# @return [Object] Result of the block
|
|
106
|
+
def session
|
|
107
|
+
@pool.session do |t|
|
|
108
|
+
yield(Pgtk::Spy.new(t, &@block))
|
|
109
|
+
end
|
|
110
|
+
end
|
|
100
111
|
end
|
data/lib/pgtk/stash.rb
CHANGED
|
@@ -149,6 +149,16 @@ class Pgtk::Stash
|
|
|
149
149
|
end
|
|
150
150
|
end
|
|
151
151
|
|
|
152
|
+
# Run statements on a single connection, without a transaction.
|
|
153
|
+
#
|
|
154
|
+
# @yield [Pgtk::Stash] A stash bound to the connection
|
|
155
|
+
# @return [Object] The result of the block
|
|
156
|
+
def session
|
|
157
|
+
@pool.session do |t|
|
|
158
|
+
yield(Pgtk::Stash.new(t, stash: @stash, loog: @loog, entrance: @entrance))
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
152
162
|
private
|
|
153
163
|
|
|
154
164
|
def queries
|
data/lib/pgtk/version.rb
CHANGED