tobox 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e47d46ec5d5f20a122b8667f00227517002ea4503348a253e3e16cd6cabe281
4
- data.tar.gz: 93fbcdbd7280e21249d4f798b7d86dac70cc8ff9847873d6a8368bda371ccf4d
3
+ metadata.gz: ecf0e9576a8a59834eb6b84eed5c648a2fda3e50b4be49fba068f2bcfc785978
4
+ data.tar.gz: fb8dc2819591dfe63a177dc1f27b9a947712db00bf451a8f3633d305ee12172b
5
5
  SHA512:
6
- metadata.gz: bc3f385c64603c6a9b8f95f32e9c38d2974080b0df50a6530505c3d5438d3d60a3ecf66b06200beedce9de23838f0e6dbb6e2aca65233180107e362538905853
7
- data.tar.gz: 5cb0d36a97a6bc173dfbfe01fc834a483848faf4157482b982551ffeb1eec3129dccd59b83cf65d9eab034c4560a7809699557a62dece8046f1944e55bcd9ee4
6
+ metadata.gz: 4b0d7eae10175ce51332e32ad89613196f7b56d01f54670bd78a36af0d411081fda20af93f7c2eee0fd032da84f7c098ad662b6ce00e01b8ab603b6f1f06cc4f
7
+ data.tar.gz: 6db739a849af63cee915970ea1abc7df4a9d4aff91edb4c76cc4c78273e7231750771638ff0dc477bbb586fc24f0dfab1de793d875cd22bb395c5ff1d3772641
data/CHANGELOG.md CHANGED
@@ -1,36 +1,72 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.6] - 2002-10-06
3
+ ## [0.2.0] - 2022-12-05
4
+
5
+ ### Features
6
+
7
+ #### Ordered event processing
8
+
9
+ When the outbox table contains a `:group_id` table (and the producer fills up events with it), then a group of events with the same `:group_id` will be processed one by one, by order of insertion.
10
+
11
+ ```ruby
12
+ # migration
13
+ create_table(:outbox) do
14
+ column :message_group_id, :integer
15
+
16
+ # tobox.rb
17
+ message_group_column :group_id
18
+
19
+ # event production
20
+ DB[:outbox].insert(event_type: "order_created", message_group_id: order.id, ....
21
+ DB[:outbox].insert(event_type: "billing_event_started", message_group_id: order.id, ....
22
+
23
+ # order_created handled first, billing_event_started only after
24
+ ```
25
+
26
+ #### on_error_worker callback
27
+
28
+ The config option `on_error_worker { |error| }` gets called when an error happens in a worker **before** events are processed (p.ex. when the database connection becomes unhealthy). You can use it to report such errors to an error reporting system (the `sentry` plugin relies on it).
29
+
30
+ ```ruby
31
+ # tobox.rb
32
+ on_error_worker { |error| Sentry.capture_exception(error, hint: { background: false }) }
33
+ ```
34
+
35
+ ### Bugfixes
36
+
37
+ Thread workers: when errors happen which bring down the workers (such as database becoming unresponsive), workers will be restarted.
38
+
39
+ ## [0.1.6] - 2022-10-06
4
40
 
5
41
  ### Bugfixes
6
42
 
7
43
  Allow passing datadog options, initialize tracing from plugin.
8
44
 
9
- ## [0.1.5] - 2002-10-06
45
+ ## [0.1.5] - 2022-10-06
10
46
 
11
47
  ### Bugfixes
12
48
 
13
49
  Fixing datadog plugin name.
14
50
 
15
- ## [0.1.4] - 2002-10-06
51
+ ## [0.1.4] - 2022-10-06
16
52
 
17
53
  ### Bugfixes
18
54
 
19
55
  Actual fix for missing datadog constants.
20
56
 
21
- ## [0.1.3] - 2002-10-06
57
+ ## [0.1.3] - 2022-10-06
22
58
 
23
59
  ### Bugfixes
24
60
 
25
61
  Datadog constants unproperly namespaced.
26
62
 
27
- ## [0.1.2] - 2002-09-14
63
+ ## [0.1.2] - 2022-09-14
28
64
 
29
65
  ### Bugfixes
30
66
 
31
67
  Actual fix for foregoing json parsing.
32
68
 
33
- ## [0.1.1] - 2002-09-14
69
+ ## [0.1.1] - 2022-09-14
34
70
 
35
71
  ### Chore
36
72
 
data/README.md CHANGED
@@ -1,11 +1,33 @@
1
1
  # Tobox: Transactional outbox pattern implementation in ruby
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/tobox.svg)](http://rubygems.org/gems/tobox)
4
- [![pipeline status](https://gitlab.com/honeyryderchuck/tobox/badges/master/pipeline.svg)](https://gitlab.com/honeyryderchuck/tobox/pipelines?page=1&scope=all&ref=master)
5
- [![coverage report](https://gitlab.com/honeyryderchuck/tobox/badges/master/coverage.svg?job=coverage)](https://honeyryderchuck.gitlab.io/tobox/#_AllFiles)
4
+ [![pipeline status](https://gitlab.com/os85/tobox/badges/master/pipeline.svg)](https://gitlab.com/os85/tobox/pipelines?page=1&scope=all&ref=master)
5
+ [![coverage report](https://gitlab.com/os85/tobox/badges/master/coverage.svg?job=coverage)](https://os85.gitlab.io/tobox/#_AllFiles)
6
6
 
7
7
  Simple, data-first events processing framework based on the [transactional outbox pattern](https://microservices.io/patterns/data/transactional-outbox.html).
8
8
 
9
+ <!-- TOC -->
10
+
11
+ - [Requirements](#requirements)
12
+ - [Installation](#installation)
13
+ - [Usage](#usage)
14
+ - [Configuration](#configuration)
15
+ - [Event](#event)
16
+ - [Features](#features)
17
+ - [Ordered event processing](#ordered-event-processing)
18
+ - [Plugins](#plugins)
19
+ - [Zeitwerk](#zeitwerk)
20
+ - [Sentry](#sentry)
21
+ - [Datadog](#datadog)
22
+ - [Supported Rubies](#supported-rubies)
23
+ - [Rails support](#rails-support)
24
+ - [Why?](#why)
25
+ - [Development](#development)
26
+ - [Contributing](#contributing)
27
+
28
+ <!-- /TOC -->
29
+
30
+ <a id="markdown-requirements" name="requirements"></a>
9
31
  ## Requirements
10
32
 
11
33
  `tobox` requires integration with RDBMS which supports `SKIP LOCKED` functionality. As of today, that's:
@@ -15,6 +37,7 @@ Simple, data-first events processing framework based on the [transactional outbo
15
37
  * Oracle
16
38
  * Microsoft SQL Server
17
39
 
40
+ <a id="markdown-installation" name="installation"></a>
18
41
  ## Installation
19
42
 
20
43
  Add this line to your application's Gemfile:
@@ -22,7 +45,7 @@ Add this line to your application's Gemfile:
22
45
  ```ruby
23
46
  gem "tobox"
24
47
 
25
- # You'll also need to aadd the right database client gem for the target RDBMS
48
+ # You'll also need to add the right database client gem for the target RDBMS
26
49
  # ex, for postgresql:
27
50
  #
28
51
  # gem "pg"
@@ -37,6 +60,8 @@ Or install it yourself as:
37
60
 
38
61
  $ gem install tobox
39
62
 
63
+
64
+ <a id="markdown-usage" name="usage"></a>
40
65
  ## Usage
41
66
 
42
67
  1. create the `outbox` table in your application's database:
@@ -80,11 +105,14 @@ end
80
105
  on("user_updated") do |event|
81
106
  # ...
82
107
  end
108
+ on("user_created", "user_updated") do |event|
109
+ # ...
110
+ end
83
111
  ```
84
112
 
85
113
  3. Start the `tobox` process
86
114
 
87
- ```
115
+ ```bash
88
116
  > bundle exec tobox -C path/to/tobox.rb -r path/to/file_requiring_application_code.rb
89
117
  ```
90
118
 
@@ -135,11 +163,12 @@ CREATE TRIGGER order_created_outbox_event
135
163
  EXECUTE PROCEDURE order_created_outbox_event();
136
164
  ```
137
165
 
166
+ <a id="markdown-configuration" name="configuration"></a>
138
167
  ## Configuration
139
168
 
140
169
  As mentioned above, configuration can be set in a particular file. The following options are configurable:
141
170
 
142
- ### `environment``
171
+ ### `environment`
143
172
 
144
173
  Sets the application environment (either "development" or "production"). Can be set directly, or via `APP_ENV` environment variable (defaults to "development").
145
174
 
@@ -228,6 +257,15 @@ callback executed when an exception was raised while processing an event.
228
257
  on_error_event { |event, exception| Sentry.capture_exception(exception) }
229
258
  ```
230
259
 
260
+ ### `on_error_worker { |error| }`
261
+
262
+ callback executed when an exception was raised in the worker, before processing events.
263
+
264
+
265
+ ```ruby
266
+ on_error_worker { |exception| Sentry.capture_exception(exception) }
267
+ ```
268
+
231
269
  ### `message_to_arguments { |event| }`
232
270
 
233
271
  if exposing raw data to the `on` handlers is not what you'd want, you can always override the behaviour by providing an alternative "before/after fetcher" implementation.
@@ -257,6 +295,11 @@ Overrides the internal logger (an instance of `Logger`).
257
295
 
258
296
  Overrides the default log level ("info" when in "production" environment, "debug" otherwise).
259
297
 
298
+ ### group_column
299
+
300
+ Defines the column to be used for event grouping, when [ordered processing of events is a requirement](#ordered-event-processing).
301
+
302
+ <a id="markdown-event" name="event"></a>
260
303
  ## Event
261
304
 
262
305
  The event is composed of the following properties:
@@ -269,20 +312,57 @@ The event is composed of the following properties:
269
312
 
270
313
  (*NOTE*: The event is also composed of other properties which are only relevant for `tobox`.)
271
314
 
272
- ## Rails support
315
+ <a id="markdown-features" name="features"></a>
316
+ ## Features
273
317
 
274
- Rails is supported out of the box by adding the [sequel-activerecord_connection](https://github.com/janko/sequel-activerecord_connection) gem into your Gemfile, and requiring the rails application in the `tobox` cli call:
318
+ There are a few extra features you can run on top a "vanilla" transactional outbox implementation. This is how you can accomplish them using `tobox`.
275
319
 
276
- ```bash
277
- > bundle exec tobox -C path/to/tobox.rb -r path/to/rails_app/config/environment.rb
320
+ <a id="markdown-ordered-event-processing" name="ordered-event-processing"></a>
321
+ ### Ordered event processing
322
+
323
+ By default, events are taken and processed from the "outbox" table concurrently by workers, which means that, while worker A may process the most recent event, and worker B takes the following, worker B may process it faster than worker A. This may be an issue if the consumer expects events from a certain context to arrive in a certain order.
324
+
325
+ One solution is to have a single worker processing the "outbox" events. Another is to use the `group_column` configuration.
326
+
327
+ What you have to do is:
328
+
329
+ 1. add a "group id" column to the "outbox" table
330
+
331
+ ```ruby
332
+ create_table(:outbox) do
333
+ primary_key :id
334
+ column :group_id, :integer
335
+ # The type is irrelevant, could also be :string, :uuid...
336
+ # ..
278
337
  ```
279
338
 
280
- In the `tobox` config, you can set the environment:
339
+ 2. set the "group_column" configuration
281
340
 
282
341
  ```ruby
283
- environment Rails.env
342
+ # in your tobox.rb
343
+ group_column :group_id
344
+ index :group_id
284
345
  ```
285
346
 
347
+ 3. insert related outbox events with the same group id
348
+
349
+ ```ruby
350
+ order = Order.new(
351
+ item_id: item.id,
352
+ price: 20_20,
353
+ currency: "EUR"
354
+ )
355
+ DB.transaction do
356
+ order.save
357
+ DB[:outbox].insert(event_type: "order_created", group_id: order.id, data_after: order.to_hash)
358
+ DB[:outbox].insert(event_type: "billing_event_started", group_id: order.id, data_after: order.to_hash)
359
+ end
360
+
361
+ # "order_created" will be processed first
362
+ # "billing_event_created" will only start processing once "order_created" finishes
363
+ ```
364
+
365
+ <a id="markdown-plugins" name="plugins"></a>
286
366
  ## Plugins
287
367
 
288
368
  `tobox` ships with a very simple plugin system. (TODO: add docs).
@@ -296,6 +376,7 @@ plugin(:plugin_name)
296
376
 
297
377
  It ships with the following integrations.
298
378
 
379
+ <a id="markdown-zeitwerk" name="zeitwerk"></a>
299
380
  ### Zeitwerk
300
381
 
301
382
  (requires the `zeitwerk` gem.)
@@ -310,6 +391,7 @@ zeitwerk_loader do |loader|
310
391
  end
311
392
  ```
312
393
 
394
+ <a id="markdown-sentry" name="sentry"></a>
313
395
  ### Sentry
314
396
 
315
397
  (requires the `sentry-ruby` gem.)
@@ -321,6 +403,7 @@ Plugin for the [sentry](https://github.com/getsentry/sentry-ruby) ruby SDK for e
321
403
  plugin(:sentry)
322
404
  ```
323
405
 
406
+ <a id="markdown-datadog" name="datadog"></a>
324
407
  ### Datadog
325
408
 
326
409
  (requires the `ddtrace` gem.)
@@ -337,10 +420,28 @@ end
337
420
  plugin(:datadog)
338
421
  ```
339
422
 
423
+ <a id="markdown-supported-rubies" name="supported-rubies"></a>
340
424
  ## Supported Rubies
341
425
 
342
426
  All Rubies greater or equal to 2.6, and always latest JRuby and Truffleruby.
343
427
 
428
+
429
+ <a id="markdown-rails-support" name="rails-support"></a>
430
+ ## Rails support
431
+
432
+ Rails is supported out of the box by adding the [sequel-activerecord_connection](https://github.com/janko/sequel-activerecord_connection) gem into your Gemfile, and requiring the rails application in the `tobox` cli call:
433
+
434
+ ```bash
435
+ > bundle exec tobox -C path/to/tobox.rb -r path/to/rails_app/config/environment.rb
436
+ ```
437
+
438
+ In the `tobox` config, you can set the environment:
439
+
440
+ ```ruby
441
+ environment Rails.env
442
+ ```
443
+
444
+ <a id="markdown-why" name="why"></a>
344
445
  ## Why?
345
446
 
346
447
  ### Simple and lightweight, framework (and programming language) agnostic
@@ -375,10 +476,12 @@ By using the database as the message broker, `tobox` can rely on good old transa
375
476
 
376
477
  (The actual processing may change this to "at least once", as issues may happen before the event is successfully deleted from the outbox. Still, "at least once" is acceptable and solvable using idempotency mechanisms).
377
478
 
479
+ <a id="markdown-development" name="development"></a>
378
480
  ## Development
379
481
 
380
482
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
381
483
 
484
+ <a id="markdown-contributing" name="contributing"></a>
382
485
  ## Contributing
383
486
 
384
- Bug reports and pull requests are welcome on GitHub at https://gitlab.com/honeyryderchuck/tobox.
487
+ Bug reports and pull requests are welcome on GitHub at https://gitlab.com/os85/tobox.
@@ -5,10 +5,6 @@ module Tobox
5
5
  def initialize(configuration)
6
6
  @configuration = configuration
7
7
  @running = false
8
- end
9
-
10
- def start
11
- return if @running
12
8
 
13
9
  worker = @configuration[:worker]
14
10
 
@@ -17,7 +13,12 @@ module Tobox
17
13
  when :fiber then FiberPool
18
14
  else worker
19
15
  end.new(@configuration)
16
+ end
17
+
18
+ def start
19
+ return if @running
20
20
 
21
+ @pool.start
21
22
  @running = true
22
23
  end
23
24
 
@@ -17,6 +17,7 @@ module Tobox
17
17
  log_level: nil,
18
18
  database_uri: nil,
19
19
  table: :outbox,
20
+ group_column: nil,
20
21
  max_attempts: 10,
21
22
  exponential_retry_factor: 4,
22
23
  wait_for_events_delay: 5,
@@ -60,8 +61,10 @@ module Tobox
60
61
  freeze
61
62
  end
62
63
 
63
- def on(event, &callback)
64
- (@handlers[event.to_sym] ||= []) << callback
64
+ def on(*events, &callback)
65
+ events.each do |event|
66
+ (@handlers[event.to_sym] ||= []) << callback
67
+ end
65
68
  self
66
69
  end
67
70
 
@@ -80,6 +83,11 @@ module Tobox
80
83
  self
81
84
  end
82
85
 
86
+ def on_error_worker(&callback)
87
+ (@lifecycle_events[:error_worker] ||= []) << callback
88
+ self
89
+ end
90
+
83
91
  def message_to_arguments(&callback)
84
92
  @arguments_handler = callback
85
93
  self
data/lib/tobox/fetcher.rb CHANGED
@@ -19,6 +19,7 @@ module Tobox
19
19
  @db.loggers << @logger unless @configuration[:environment] == "production"
20
20
 
21
21
  @table = configuration[:table]
22
+ @group_column = configuration[:group_column]
22
23
  @exponential_retry_factor = configuration[:exponential_retry_factor]
23
24
 
24
25
  max_attempts = configuration[:max_attempts]
@@ -33,9 +34,6 @@ module Tobox
33
34
  @pick_next_sql = @ds.where(Sequel[@table][:attempts] < max_attempts) # filter out exhausted attempts
34
35
  .where(run_at_conds)
35
36
  .order(Sequel.desc(:run_at, nulls: :first), :id)
36
- .for_update
37
- .skip_locked
38
- .limit(1)
39
37
 
40
38
  @before_event_handlers = Array(@configuration.lifecycle_events[:before_event])
41
39
  @after_event_handlers = Array(@configuration.lifecycle_events[:after_event])
@@ -44,8 +42,34 @@ module Tobox
44
42
 
45
43
  def fetch_events(&blk)
46
44
  num_events = 0
47
- @db.transaction do
48
- event_ids = @pick_next_sql.select_map(:id) # lock starts here
45
+ @db.transaction(savepoint: false) do
46
+ if @group_column
47
+ group = @pick_next_sql.for_update
48
+ .skip_locked
49
+ .limit(1)
50
+ .select(@group_column)
51
+
52
+ # get total from a group, to compare to the number of future locked rows.
53
+ total_from_group = @ds.where(@group_column => group).count
54
+
55
+ event_ids = @ds.where(@group_column => group)
56
+ .order(Sequel.desc(:run_at, nulls: :first), :id)
57
+ .for_update.skip_locked.select_map(:id)
58
+
59
+ if event_ids.size != total_from_group
60
+ # this happens if concurrent workers locked different rows from the same group,
61
+ # or when new rows from a given group have been inserted after the lock has been
62
+ # acquired
63
+ event_ids = []
64
+ end
65
+
66
+ # lock all, process 1
67
+ event_ids = event_ids[0, 1]
68
+ else
69
+ event_ids = @pick_next_sql.for_update
70
+ .skip_locked
71
+ .limit(1).select_map(:id) # lock starts here
72
+ end
49
73
 
50
74
  events = nil
51
75
  error = nil
@@ -130,6 +130,10 @@ module Tobox
130
130
  config.on_after_event(&event_handler.method(:on_finish))
131
131
  config.on_error_event(&event_handler.method(:on_error))
132
132
 
133
+ config.on_error_worker do |error|
134
+ ::Sentry.capture_exception(error, hint: { background: false })
135
+ end
136
+
133
137
  ::Sentry::Configuration.attr_reader(:tobox)
134
138
  ::Sentry::Configuration.add_post_initialization_callback do
135
139
  @tobox = Plugins::Sentry::Configuration.new
@@ -5,12 +5,9 @@ require "fiber_scheduler"
5
5
 
6
6
  module Tobox
7
7
  class FiberPool < Pool
8
- class KillError < Interrupt; end
9
-
10
8
  def initialize(_configuration)
11
9
  Sequel.extension(:fiber_concurrency)
12
10
  super
13
- @error_handlers = Array(@configuration.lifecycle_events[:error])
14
11
  end
15
12
 
16
13
  def start
@@ -19,14 +16,7 @@ module Tobox
19
16
 
20
17
  FiberScheduler do
21
18
  @workers.each_with_index do |wk, _idx|
22
- Fiber.schedule do
23
- wk.work
24
- rescue KillError
25
- # noop
26
- rescue Exception => e # rubocop:disable Lint/RescueException
27
- @error_handlers.each { |hd| hd.call(:tobox_error, e) }
28
- raise e
29
- end
19
+ Fiber.schedule { do_work(wk) }
30
20
  end
31
21
  end
32
22
  end
@@ -1,32 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "monitor"
4
+
3
5
  module Tobox
4
6
  class ThreadedPool < Pool
5
- class KillError < Interrupt; end
6
-
7
7
  def initialize(_configuration)
8
+ @parent_thread = Thread.main
8
9
  @threads = []
10
+ @threads.extend(MonitorMixin)
9
11
  super
10
- @error_handlers = Array(@configuration.lifecycle_events[:error])
11
12
  end
12
13
 
13
14
  def start
14
- @workers.each_with_index do |wk, idx|
15
- th = Thread.start do
16
- Thread.current.name = "tobox-worker-#{idx}"
17
-
18
- begin
19
- wk.work
20
- rescue KillError
21
- # noop
22
- rescue Exception => e # rubocop:disable Lint/RescueException
23
- @error_handlers.each { |hd| hd.call(:tobox_error, e) }
24
- raise e
25
- end
26
-
27
- @threads.delete(Thread.current)
15
+ @workers.each do |wk|
16
+ th = start_thread_worker(wk)
17
+ @threads.synchronize do
18
+ @threads << th
28
19
  end
29
- @threads << th
30
20
  end
31
21
  end
32
22
 
@@ -51,5 +41,30 @@ module Tobox
51
41
  th.value # waits
52
42
  end
53
43
  end
44
+
45
+ private
46
+
47
+ def start_thread_worker(wrk)
48
+ Thread.start(wrk) do |worker|
49
+ Thread.current.name = worker.label
50
+
51
+ do_work(worker)
52
+
53
+ @threads.synchronize do
54
+ @threads.delete(Thread.current)
55
+
56
+ if worker.finished? && @running
57
+ idx = @workers.index(worker)
58
+
59
+ subst_worker = Worker.new(worker.label, @configuration)
60
+ @workers[idx] = subst_worker
61
+ subst_thread = start_thread_worker(subst_worker)
62
+ @threads << subst_thread
63
+ end
64
+ # all workers went down abruply, we need to kill the process.
65
+ # @parent_thread.raise(Interrupt) if wk.finished? && @threads.empty? && @running
66
+ end
67
+ end
68
+ end
54
69
  end
55
70
  end
data/lib/tobox/pool.rb CHANGED
@@ -2,17 +2,39 @@
2
2
 
3
3
  module Tobox
4
4
  class Pool
5
+ class KillError < Interrupt; end
6
+
5
7
  def initialize(configuration)
6
8
  @configuration = configuration
9
+ @logger = @configuration.default_logger
7
10
  @num_workers = configuration[:concurrency]
8
11
  @workers = Array.new(@num_workers) do |idx|
9
12
  Worker.new("tobox-worker-#{idx}", configuration)
10
13
  end
11
- start
14
+ @worker_error_handlers = Array(@configuration.lifecycle_events[:error_worker])
15
+ @running = true
12
16
  end
13
17
 
14
18
  def stop
19
+ return unless @running
20
+
15
21
  @workers.each(&:finish!)
22
+ @running = false
23
+ end
24
+
25
+ def do_work(wrk)
26
+ wrk.work
27
+ rescue KillError
28
+ # noop
29
+ rescue Exception => e # rubocop:disable Lint/RescueException
30
+ wrk.finish!
31
+ @logger.error do
32
+ "(worker: #{wrk.label}) -> " \
33
+ "crashed with error\n" \
34
+ "#{e.class}: #{e.message}\n" \
35
+ "#{e.backtrace.join("\n")}"
36
+ end
37
+ @worker_error_handlers.each { |hd| hd.call(e) }
16
38
  end
17
39
  end
18
40
 
data/lib/tobox/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tobox
4
- VERSION = "0.1.6"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/tobox/worker.rb CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  module Tobox
4
4
  class Worker
5
+ attr_reader :label
6
+
5
7
  def initialize(label, configuration)
8
+ @label = label
6
9
  @wait_for_events_delay = configuration[:wait_for_events_delay]
7
10
  @handlers = configuration.handlers || {}
8
11
  @fetcher = Fetcher.new(label, configuration)
@@ -13,6 +16,10 @@ module Tobox
13
16
  define_singleton_method(:message_to_arguments, &message_to_arguments)
14
17
  end
15
18
 
19
+ def finished?
20
+ @finished
21
+ end
22
+
16
23
  def finish!
17
24
  @finished = true
18
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tobox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - HoneyryderChuck
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-06 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -52,15 +52,15 @@ files:
52
52
  - lib/tobox/pool/threaded_pool.rb
53
53
  - lib/tobox/version.rb
54
54
  - lib/tobox/worker.rb
55
- homepage: https://gitlab.com/honeyryderchuck/tobox
55
+ homepage: https://gitlab.com/os85/tobox
56
56
  licenses: []
57
57
  metadata:
58
- homepage_uri: https://gitlab.com/honeyryderchuck/tobox
58
+ homepage_uri: https://gitlab.com/os85/tobox
59
59
  allowed_push_host: https://rubygems.org
60
- source_code_uri: https://gitlab.com/honeyryderchuck/tobox
61
- bug_tracker_uri: https://gitlab.com/honeyryderchuck/tobox/issues
62
- documentation_uri: https://gitlab.com/honeyryderchuck/tobox
63
- changelog_uri: https://gitlab.com/honeyryderchuck/tobox/-/blob/master/CHANGELOG.md
60
+ source_code_uri: https://gitlab.com/os85/tobox
61
+ bug_tracker_uri: https://gitlab.com/os85/tobox/issues
62
+ documentation_uri: https://gitlab.com/os85/tobox
63
+ changelog_uri: https://gitlab.com/os85/tobox/-/blob/master/CHANGELOG.md
64
64
  rubygems_mfa_required: 'true'
65
65
  post_install_message:
66
66
  rdoc_options: []