gouda 0.2.0 → 0.2.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: 6a5b6d65b9cbfbe699e5bbfe1dd2854eeebc74d711d22243ec9c1c647d6986f7
4
- data.tar.gz: d2642c37fe82af94a577d6b0806e9178842b8b0a53b64fe2eefeb1362f748a06
3
+ metadata.gz: 225a9cde8e106f517e71827c18bb5d189b6570b3b8717f91c59ecd263235773a
4
+ data.tar.gz: 165421a35c9f0a9b969e105b3c83867c2ca184b3d9fdc428e2c1d21121c92795
5
5
  SHA512:
6
- metadata.gz: 8d276d47fd5dced75511522900f1328ee1cb7cb076f833e6dc0d8eb597cafdc1933986ebb17a2ec37390d0d3e74b2c183fdabba204cc0e41c2010ccb2adefcdb
7
- data.tar.gz: 644d5eba7e6fca4fbf2f21d805d98985be8e72fcfa5e06dc8402a26fefb292c2a204134071e0e31ca345ab74863ea6191aa934479e6eb1b865a31e4bea2ff817
6
+ metadata.gz: dcf1832c6f23778920eccb160878aba29e6d00c141722a7398cd05b81e44a2f0668520ca5eef964217d62d1e06b87f892cb745813ae5cdbfc6a252f3e70cf3a8
7
+ data.tar.gz: 26732655634330f34ac7d8c4f1b32b8a6e27a450d32b824d65a9d960cf888362e460d4f4e9cf2ae57fbaf4ec3a755ad1ad02d0ce73fbaf6d7f490349e780e99c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.2.1]
2
+
3
+ - Fix a potential memory leak in `in_bulk`. Thanks to Julik.
4
+
1
5
  ## [0.2.0]
2
6
 
3
7
  - Introduce fiber execution for workers
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- gouda (0.2.0)
4
+ gouda (0.2.1)
5
5
  activejob (>= 7.2.0)
6
6
  activerecord (>= 7.2.0)
7
7
  activesupport (>= 7.2.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- gouda (0.2.0)
4
+ gouda (0.2.1)
5
5
  activejob (>= 7.2.0)
6
6
  activerecord (>= 7.2.0)
7
7
  activesupport (>= 7.2.0)
data/lib/gouda/bulk.rb CHANGED
@@ -18,7 +18,8 @@ module Gouda
18
18
  # end
19
19
  # @return [Object] the return value of the block
20
20
  def self.in_bulk(&blk)
21
- if Thread.current[:gouda_bulk_buffer].nil?
21
+ outermost = Thread.current[:gouda_bulk_buffer].nil?
22
+ if outermost
22
23
  Thread.current[:gouda_bulk_buffer] = []
23
24
  retval = yield
24
25
  buf, Thread.current[:gouda_bulk_buffer] = Thread.current[:gouda_bulk_buffer], nil
@@ -27,6 +28,8 @@ module Gouda
27
28
  else # There already is an open bulk
28
29
  yield
29
30
  end
31
+ ensure
32
+ Thread.current[:gouda_bulk_buffer] = nil if outermost
30
33
  end
31
34
 
32
35
  # This method exists in edge Rails so probably can be replaced later:
data/lib/gouda/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gouda
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -4,6 +4,7 @@ require "gouda/test_helper"
4
4
 
5
5
  class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
6
6
  include AssertHelper
7
+
7
8
  class TestJobWithoutConcurrency < ActiveJob::Base
8
9
  self.queue_adapter = Gouda::Adapter.new
9
10
  end
@@ -11,6 +12,7 @@ class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
11
12
  class TestJobWithPerformConcurrency < ActiveJob::Base
12
13
  self.queue_adapter = Gouda::Adapter.new
13
14
  include Gouda::ActiveJobExtensions::Concurrency
15
+
14
16
  gouda_control_concurrency_with(perform_limit: 1)
15
17
 
16
18
  def perform(*args)
@@ -42,6 +44,7 @@ class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
42
44
  class TestJobWithCommonConcurrency < ActiveJob::Base
43
45
  self.queue_adapter = Gouda::Adapter.new
44
46
  include Gouda::ActiveJobExtensions::Concurrency
47
+
45
48
  gouda_control_concurrency_with(total_limit: 1)
46
49
 
47
50
  def perform(*args)
@@ -79,6 +82,7 @@ class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
79
82
  class TestJobWithEnqueueConcurrency < ActiveJob::Base
80
83
  self.queue_adapter = Gouda::Adapter.new
81
84
  include Gouda::ActiveJobExtensions::Concurrency
85
+
82
86
  gouda_control_concurrency_with(enqueue_limit: 1)
83
87
 
84
88
  def perform(*args)
@@ -105,6 +109,7 @@ class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
105
109
  class TestJobWithCustomKey < ActiveJob::Base
106
110
  self.queue_adapter = Gouda::Adapter.new
107
111
  include Gouda::ActiveJobExtensions::Concurrency
112
+
108
113
  gouda_control_concurrency_with total_limit: 1, key: "42"
109
114
  end
110
115
 
@@ -117,6 +122,7 @@ class GoudaConcurrencyExtensionTest < ActiveSupport::TestCase
117
122
  class TestJobWithCustomKeyProc < ActiveJob::Base
118
123
  self.queue_adapter = Gouda::Adapter.new
119
124
  include Gouda::ActiveJobExtensions::Concurrency
125
+
120
126
  gouda_control_concurrency_with total_limit: 1, key: -> { @ivar }
121
127
 
122
128
  def initialize(...)
@@ -58,6 +58,7 @@ class GoudaTest < ActiveSupport::TestCase
58
58
 
59
59
  class JobWithEnqueueConcurrencyViaGoudaAndEnqueueLimit < GoudaTestJob
60
60
  include Gouda::ActiveJobExtensions::Concurrency
61
+
61
62
  gouda_control_concurrency_with(enqueue_limit: 1, key: -> { self.class.to_s })
62
63
  def perform
63
64
  "perform result of #{self.class}"
@@ -66,6 +67,7 @@ class GoudaTest < ActiveSupport::TestCase
66
67
 
67
68
  class JobWithEnqueueConcurrencyViaGoudaAndTotalLimit < GoudaTestJob
68
69
  include Gouda::ActiveJobExtensions::Concurrency
70
+
69
71
  gouda_control_concurrency_with(total_limit: 1, key: -> { self.class.to_s })
70
72
  def perform
71
73
  "perform result of #{self.class}"
@@ -84,6 +86,7 @@ class GoudaTest < ActiveSupport::TestCase
84
86
 
85
87
  class JobWithExecutionConcurrencyViaGoudaAndTotalLimit < GoudaTestJob
86
88
  include Gouda::ActiveJobExtensions::Concurrency
89
+
87
90
  gouda_control_concurrency_with(total_limit: 1, key: -> { self.class.to_s })
88
91
  def perform
89
92
  "perform result of #{self.class}"
@@ -92,6 +95,7 @@ class GoudaTest < ActiveSupport::TestCase
92
95
 
93
96
  class JobWithExecutionConcurrencyViaGoudaAndPerformLimit < GoudaTestJob
94
97
  include Gouda::ActiveJobExtensions::Concurrency
98
+
95
99
  gouda_control_concurrency_with(perform_limit: 1, key: -> { self.class.to_s })
96
100
  def perform
97
101
  "perform result of #{self.class}"
@@ -384,6 +388,29 @@ class GoudaTest < ActiveSupport::TestCase
384
388
  end
385
389
  end
386
390
 
391
+ test "resets the bulk buffer thread local when the block raises" do
392
+ assert_raises(RuntimeError) do
393
+ Gouda.in_bulk do
394
+ raise "boom"
395
+ end
396
+ end
397
+ assert_nil Thread.current[:gouda_bulk_buffer], "The bulk buffer thread local must be reset after an exception"
398
+ end
399
+
400
+ test "enqueues jobs normally after a failed in_bulk block" do
401
+ assert_raises(RuntimeError) do
402
+ Gouda.in_bulk do
403
+ StandardJob.perform_later
404
+ raise "boom"
405
+ end
406
+ end
407
+
408
+ # Jobs enqueued after the failed bulk block should still be enqueued normally
409
+ assert_changes_by(-> { Gouda::Workload.count }, exactly: 1) do
410
+ StandardJob.perform_later
411
+ end
412
+ end
413
+
387
414
  test "sets the correct queue with perform_later" do
388
415
  assert_changes_by(-> { Gouda::Workload.count }, exactly: 1) do
389
416
  HeavyJob.perform_later
@@ -19,6 +19,7 @@ class GoudaSchedulerTest < ActiveSupport::TestCase
19
19
 
20
20
  class FailingJob < ActiveJob::Base
21
21
  include Gouda::ActiveJobExtensions::Concurrency
22
+
22
23
  self.queue_adapter = Gouda::Adapter.new
23
24
 
24
25
  class MegaError < StandardError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gouda
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian van Hesteren
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-08-04 00:00:00.000000000 Z
12
+ date: 2026-02-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord