pgtk 0.24.3 → 0.25.0

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/stash.rb +41 -12
  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: bc06629facf30f84cc049cd8404c347129c286edfd82c15d75382930d44456aa
4
- data.tar.gz: 27a43238939e20b6b8aa5356924fd2a18e10d78c10190dda446cea2c57edf004
3
+ metadata.gz: b21dae64f611c7570502547af5c940397cbc247e45f7426f5e349c6308f7fa57
4
+ data.tar.gz: ec130297606a929b7774b350ae74ac0a7e4b66222eeaeaaa5ba7a4e363cd11ae
5
5
  SHA512:
6
- metadata.gz: 17d9b5d89759f159db6f0dea44a679bda49d05005b4f2215d2d174f8e92a09dbcb1ce5388e01fcf1ce7a0c6105dd2c4968f428f9c9a640946e4e14dcffeffd54
7
- data.tar.gz: 14a6aff5628756724cd356e83345a1f111be05a006eab4aa034b1c397253dac72f293b68b218eb06d9d17a0a549ca0477081e34b658de8ff1c05cecbe577d0b6
6
+ metadata.gz: 20a6203a23f64e00f9e9bfe9daf44463530820959f70d512d560e3dc0b73e8d9b2b2d453361d37c23a484208630d06654d139518f3188aec0eab18cb4c1817a5
7
+ data.tar.gz: a985cd2ab24bfc68927b46f1852ac1b06f10ad642aac41d23f8294ef66065020796f702f58df8e5c1ae03da8fc1a716a9fcc1c5349a58ee1d983e67b56398374
data/lib/pgtk/stash.rb CHANGED
@@ -44,16 +44,20 @@ class Pgtk::Stash
44
44
  # @param [Object] pool The underlying connection pool that executes actual database queries
45
45
  # @param [Hash] stash Internal cache structure containing queries and tables hashes for sharing state
46
46
  # across transactions
47
- # @param [Integer] refill_interval Interval in seconds between background tasks that recalculate stale
47
+ # @param [Float] refill_interval Interval in seconds between background tasks that recalculate stale
48
48
  # cached queries
49
+ # @param [Float] refill_delay A pause in seconds we take before making a refill
49
50
  # @param [Integer] max_queue_length Maximum number of refilling tasks allowed in the thread pool queue
50
51
  # before new tasks are skipped
51
52
  # @param [Integer] threads Number of worker threads in the background thread pool for cache refilling
52
53
  # operations
53
54
  # @param [Integer] cap Maximum number of cached query results to retain; oldest queries are evicted when
54
55
  # this limit is exceeded
55
- # @param [Integer] cap_interval Interval in seconds between background tasks that enforce the cache size
56
+ # @param [Float] cap_interval Interval in seconds between background tasks that enforce the cache size
56
57
  # cap by removing old queries
58
+ # @param [Integer] retire Maximum age in seconds to keep a query in cache after its latest usage
59
+ # @param [Float] retire_interval Interval in seconds between background tasks that remove
60
+ # retired queries
57
61
  # @param [Loog] loog Logger instance for debugging and monitoring cache operations (default: null logger)
58
62
  # @param [Concurrent::ReentrantReadWriteLock] entrance Read-write lock for thread-safe cache access
59
63
  # shared across instances
@@ -63,10 +67,13 @@ class Pgtk::Stash
63
67
  pool,
64
68
  stash: { queries: {}, tables: {} },
65
69
  refill_interval: 16,
70
+ refill_delay: 0,
66
71
  max_queue_length: 128,
67
72
  threads: 4,
68
73
  cap: 10_000,
69
74
  cap_interval: 60,
75
+ retire: 15 * 60,
76
+ retire_interval: 60,
70
77
  loog: Loog::NULL,
71
78
  entrance: Concurrent::ReentrantReadWriteLock.new,
72
79
  launched: Concurrent::AtomicBoolean.new(false)
@@ -76,10 +83,13 @@ class Pgtk::Stash
76
83
  @launched = launched
77
84
  @entrance = entrance
78
85
  @refill_interval = refill_interval
86
+ @refill_delay = refill_delay
79
87
  @max_queue_length = max_queue_length
80
88
  @threads = threads
81
89
  @cap = cap
82
90
  @cap_interval = cap_interval
91
+ @retire = retire
92
+ @retire_interval = retire_interval
83
93
  @loog = loog
84
94
  @tpool = Concurrent::FixedThreadPool.new(@threads)
85
95
  end
@@ -122,18 +132,28 @@ class Pgtk::Stash
122
132
  [
123
133
  @pool.dump,
124
134
  '',
125
- # rubocop:disable Layout/LineLength
126
- "Pgtk::Stash (refill_interval=#{@refill_interval}s, max_queue_length=#{@max_queue_length}, threads=#{@threads}, cap=#{@cap}, cap_interval=#{@cap_interval}s):",
127
- # rubocop:enable Layout/LineLength
135
+ [
136
+ 'Pgtk::Stash (',
137
+ [
138
+ "refill_interval=#{@refill_interval}s",
139
+ "max_queue_length=#{@max_queue_length}",
140
+ "threads=#{@threads}",
141
+ "cap=#{@cap}",
142
+ "cap_interval=#{@cap_interval}s",
143
+ "retire=#{@retire}",
144
+ "retire_interval=#{@retire_interval}s"
145
+ ].join(', '),
146
+ '):'
147
+ ].join,
128
148
  " #{'not ' if @launched.false?}launched",
129
- " #{stash_size} queries stashed (#{stash_size > @cap ? 'above' : 'below'} the cap)",
130
- " #{@tpool.queue_length} task(s) in the thread pool",
131
- " #{@stash[:tables].count} table(s) in cache",
132
- " #{qq.sum { |a| a[:s] }} stale quer(ies) in cache:",
149
+ " #{stash_size} queries cached (#{stash_size > @cap ? 'above' : 'below'} the cap)",
150
+ " #{@tpool.queue_length} tasks in the thread pool",
151
+ " #{@stash[:tables].count} tables in cache",
152
+ " #{qq.sum { |a| a[:s] }} stale queries in cache:",
133
153
  qq.select { |a| a[:s].positive? }.sort_by { -_1[:p] }.take(8).map do |a|
134
154
  " #{a[:c]}/#{a[:p]}p/#{a[:s]}s/#{a[:u].ago}: #{a[:q]}"
135
155
  end,
136
- " #{qq.count { |a| a[:s].zero? }} other quer(ies) in cache:",
156
+ " #{qq.count { |a| a[:s].zero? }} other queries in cache:",
137
157
  qq.select { |a| a[:s].zero? }.sort_by { -_1[:p] }.take(16).map do |a|
138
158
  " #{a[:c]}/#{a[:p]}p/#{a[:s]}s/#{a[:u].ago}: #{a[:q]}"
139
159
  end
@@ -160,7 +180,7 @@ class Pgtk::Stash
160
180
  tables.each do |t|
161
181
  @stash[:tables][t]&.each do |q|
162
182
  @stash[:queries][q]&.each_key do |key|
163
- @stash[:queries][q][key][:stale] = true
183
+ @stash[:queries][q][key][:stale] = Time.now
164
184
  end
165
185
  end
166
186
  end
@@ -249,6 +269,14 @@ class Pgtk::Stash
249
269
  end
250
270
  end
251
271
  end
272
+ Concurrent::TimerTask.execute(execution_interval: @retire_interval, executor: @tpool) do
273
+ @entrance.with_write_lock do
274
+ @stash[:queries].each_key do |q|
275
+ @stash[:queries][q].delete_if { |_, h| h[:used] < Time.now - @retire }
276
+ @stash[:queries].delete_if { |_, kk| kk.empty? }
277
+ end
278
+ end
279
+ end
252
280
  Concurrent::TimerTask.execute(execution_interval: @refill_interval, executor: @tpool) do
253
281
  @stash[:queries]
254
282
  .map { |k, v| [k, v.values.sum { |vv| vv[:popularity] }, v.values.any? { |vv| vv[:stale] }] }
@@ -258,13 +286,14 @@ class Pgtk::Stash
258
286
  q = a[0]
259
287
  @stash[:queries][q].each_key do |k|
260
288
  next unless @stash[:queries][q][k][:stale]
289
+ next if @stash[:queries][q][k][:stale] > Time.now - @refill_delay
261
290
  next if @tpool.queue_length >= @max_queue_length
262
291
  @tpool.post do
263
292
  h = @stash[:queries][q][k]
264
293
  ret = @pool.exec(q, h[:params], h[:result])
265
294
  @entrance.with_write_lock do
266
295
  h = @stash[:queries][q][k]
267
- h[:stale] = false
296
+ h.delete(:stale)
268
297
  h[:ret] = ret
269
298
  end
270
299
  end
data/lib/pgtk/version.rb CHANGED
@@ -11,5 +11,5 @@ require_relative '../pgtk'
11
11
  # License:: MIT
12
12
  module Pgtk
13
13
  # Current version of the library.
14
- VERSION = '0.24.3'
14
+ VERSION = '0.25.0'
15
15
  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.24.3
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko