pgtk 0.31.4 → 0.31.5

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pgtk/pool.rb +62 -55
  3. data/lib/pgtk/version.rb +1 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3a43722aa806c7c496234f00c186abac8cf07dfeb48e9baa97353fca08a1e0a
4
- data.tar.gz: 63e903b575092c0bb62bf25b5aa96004723f4c4312bf3e16c4b5fc2af0b2b0c7
3
+ metadata.gz: 9986e9d0fb260d182d823661b28c2782b7cbc066348431c59f18a2541e53018f
4
+ data.tar.gz: 50c04ad428b737284568c3cc134c7b5f0cff4d8cdf9b1a02430213a31e819701
5
5
  SHA512:
6
- metadata.gz: d03c3c8458643fc95801a51b6d2fd4a61808ff934f2ac4341ea02b779d8ef688f44283f079b69a8d8bd02dc1d2733c07af4549dfcf8b41e3acceb5402083223e
7
- data.tar.gz: 842c436ab8180751b612b55a5a0f113b3db10a101c1db9dd3adf1150ac2b5961c3baa5654a7d8c4cc44ccb788c77e495c0523a235ef0e2275f6c4b12729a8fa6
6
+ metadata.gz: 0f6bf39b221fcedfc9ffd9843ef1d6ca43834d695c9a980139f60dd4915c9582f3174c5047710ecad954f62e9fad42b0fac540b9efcf5946885b7cde7da6b747
7
+ data.tar.gz: 64bd40eaa16ad9ee3684adc204d442b3ec8a19fe699c0cfc8323b19c098fcbf61ed3bf225d961bbb02cf1f16ee69b976035aaa5dd3661873ab4c3fbf00defd57
data/lib/pgtk/pool.rb CHANGED
@@ -4,6 +4,7 @@ require 'loog'
4
4
  # SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
5
5
  # SPDX-License-Identifier: MIT
6
6
 
7
+ require 'ellipsized'
7
8
  require 'pg'
8
9
  require 'tago'
9
10
  require_relative '../pgtk'
@@ -84,46 +85,7 @@ class Pgtk::Pool
84
85
  " Pgtk version: #{Pgtk::VERSION}",
85
86
  " PgSQL version: #{version}",
86
87
  " #{@pool.size} connections:",
87
- @pool.map do |c|
88
- [
89
- ' ',
90
- "##{c.backend_pid}",
91
- case c.pipeline_status
92
- when PG::Constants::PQ_PIPELINE_ON
93
- 'ON'
94
- when PG::Constants::PQ_PIPELINE_OFF
95
- 'OFF'
96
- when PG::Constants::PQ_PIPELINE_ABORTED
97
- 'ABORTED'
98
- else
99
- "pipeline_status=#{c.pipeline_status}"
100
- end,
101
- case c.status
102
- when PG::Constants::CONNECTION_OK
103
- 'OK'
104
- when PG::Constants::CONNECTION_BAD
105
- 'BAD'
106
- else
107
- "status=#{c.status}"
108
- end,
109
- case c.transaction_status
110
- when PG::Constants::PQTRANS_IDLE
111
- 'IDLE'
112
- when PG::Constants::PQTRANS_ACTIVE
113
- 'ACTIVE'
114
- when PG::Constants::PQTRANS_INTRANS
115
- 'INTRANS'
116
- when PG::Constants::PQTRANS_INERROR
117
- 'INERROR'
118
- when PG::Constants::PQTRANS_UNKNOWN
119
- 'UNKNOWN'
120
- else
121
- "transaction_status=#{c.transaction_status}"
122
- end
123
- ].join(' ')
124
- rescue PG::ConnectionBad => e
125
- e.message
126
- end
88
+ @pool.map { |conn| info(conn) }
127
89
  ].flatten.join("\n")
128
90
  end
129
91
 
@@ -311,6 +273,7 @@ class Pgtk::Pool
311
273
  def exec(query, args = [], result = 0)
312
274
  start = Time.now
313
275
  sql = query.is_a?(Array) ? query.join(' ') : query
276
+ @conn.instance_variable_set(:@pgtk_last_query, sql)
314
277
  begin
315
278
  out =
316
279
  if args.empty?
@@ -348,32 +311,76 @@ class Pgtk::Pool
348
311
 
349
312
  def connect
350
313
  conn = @pool.pop
351
- conn = renew(conn) if dead?(conn)
352
314
  begin
353
- yield(conn)
354
- rescue StandardError => e
315
+ reason = cause(conn)
316
+ if reason
317
+ begin
318
+ conn = renew(conn, reason)
319
+ rescue StandardError => e
320
+ @log.warn("Failed to renew dead connection (#{reason}): #{e.message}")
321
+ end
322
+ end
355
323
  begin
356
- conn = renew(conn)
357
- rescue StandardError => re
358
- @log.warn("Failed to renew connection after #{e.message}: #{re.message}")
324
+ yield(conn)
325
+ rescue StandardError => e
326
+ begin
327
+ conn = renew(conn, "query failed: #{e.message.strip}")
328
+ rescue StandardError => re
329
+ @log.warn("Failed to renew connection after #{e.message}: #{re.message}")
330
+ end
331
+ raise(e)
359
332
  end
360
- raise(e)
361
333
  ensure
362
334
  @pool.push(conn)
363
335
  end
364
336
  end
365
337
 
366
- def dead?(conn)
367
- conn.finished? ||
368
- conn.status == PG::Constants::CONNECTION_BAD ||
369
- conn.transaction_status != PG::Constants::PQTRANS_IDLE
370
- rescue StandardError
371
- true
338
+ def cause(conn)
339
+ return 'finished' if conn.finished?
340
+ return 'status BAD' if conn.status == PG::Constants::CONNECTION_BAD
341
+ return "transaction status #{conn.transaction_status}" if conn.transaction_status != PG::Constants::PQTRANS_IDLE
342
+ nil
343
+ rescue StandardError => e
344
+ "inspection failed: #{e.message.strip}"
372
345
  end
373
346
 
374
- def renew(conn)
347
+ def info(conn)
348
+ pipelines = { PG::Constants::PQ_PIPELINE_ON => 'ON', PG::Constants::PQ_PIPELINE_OFF => 'OFF',
349
+ PG::Constants::PQ_PIPELINE_ABORTED => 'ABORTED' }
350
+ statuses = { PG::Constants::CONNECTION_OK => 'OK', PG::Constants::CONNECTION_BAD => 'BAD' }
351
+ transactions = { PG::Constants::PQTRANS_IDLE => 'IDLE', PG::Constants::PQTRANS_ACTIVE => 'ACTIVE',
352
+ PG::Constants::PQTRANS_INTRANS => 'INTRANS', PG::Constants::PQTRANS_INERROR => 'INERROR',
353
+ PG::Constants::PQTRANS_UNKNOWN => 'UNKNOWN' }
354
+ parts = [
355
+ ' ',
356
+ "##{conn.backend_pid}",
357
+ pipelines.fetch(conn.pipeline_status, "pipeline_status=#{conn.pipeline_status}"),
358
+ statuses.fetch(conn.status, "status=#{conn.status}"),
359
+ transactions.fetch(conn.transaction_status, "transaction_status=#{conn.transaction_status}")
360
+ ]
361
+ if conn.transaction_status == PG::Constants::PQTRANS_ACTIVE
362
+ running = conn.instance_variable_get(:@pgtk_last_query)
363
+ parts << "running: #{running.gsub(/\s+/, ' ').strip.ellipsized(60)}" if running
364
+ end
365
+ parts.join(' ')
366
+ rescue PG::ConnectionBad => e
367
+ parts = [e.message.strip]
368
+ closed = conn.instance_variable_get(:@pgtk_closed_at)
369
+ parts << "#{closed.ago} ago" if closed
370
+ reason = conn.instance_variable_get(:@pgtk_closed_reason)
371
+ parts << "because: #{reason}" if reason
372
+ last = conn.instance_variable_get(:@pgtk_last_query)
373
+ parts << "last query: #{last.gsub(/\s+/, ' ').strip.ellipsized(60)}" if last
374
+ parts.join(', ')
375
+ end
376
+
377
+ def renew(conn, reason)
375
378
  begin
376
- conn.close unless conn.finished?
379
+ unless conn.finished?
380
+ conn.instance_variable_set(:@pgtk_closed_at, Time.now)
381
+ conn.instance_variable_set(:@pgtk_closed_reason, reason)
382
+ conn.close
383
+ end
377
384
  rescue StandardError => e
378
385
  @log.warn("Failed to close connection: #{e.message}")
379
386
  end
data/lib/pgtk/version.rb CHANGED
@@ -10,5 +10,5 @@ require_relative '../pgtk'
10
10
  # Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
11
11
  # License:: MIT
12
12
  module Pgtk
13
- VERSION = '0.31.4' unless defined?(VERSION)
13
+ VERSION = '0.31.5' unless defined?(VERSION)
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgtk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.4
4
+ version: 0.31.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko