local_bus 0.1.2 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3abe4359b671f5e051a9e3b4e2cb0ac73ca9c00ef63c1622c158ebf4c116a1b5
4
- data.tar.gz: 408ea743c2b5b8d3a000a8db5b8207f6e3d90edfb3976b8bf1aad3ec11dde8ab
3
+ metadata.gz: f435ed1460835bdd4b50311c366c158f4dda0381038368cd325a13c8ceace3b9
4
+ data.tar.gz: 937b58aa97ed2e9ca2f65eb02b6c401f9e93c4d590aff5966816dd6dd47be8a9
5
5
  SHA512:
6
- metadata.gz: de71a197041a072f69ad37e971663983da3f77a00889c71afc622d382e74480bf5bef25ebfdc5d97762d4a15f385b0d63bdd929f67c6e455dc378340d3afda93
7
- data.tar.gz: fe165204058f9e5f9df6aa00d4f3d07db69478eeca3232a7204be758e0b6418800e903c576c927b04b0a958946e729c385a27341bb1f9168bcb2cb83198396db
6
+ metadata.gz: 74828920b50a51ae3fc00583dee61657d88cadd62482172fc34c1e54e935a652306716242c9152d6a5f35e9660f6d52930c6840966dc281f158c391666588cf7
7
+ data.tar.gz: d7c86027a16144325f3ea4cd3e65f41ea55a56ac6b75e309a75a5397cd7042372002783948f64b6e76d3cdbb0200a1cd0b62be3ec8c632b3639c5c33b0a42a76
data/README.md CHANGED
@@ -30,22 +30,23 @@ LocalBus is a lightweight pub/sub system for Ruby that helps organize and simpli
30
30
 
31
31
  ## Table of Contents
32
32
 
33
- - [Why LocalBus?](#why-localbus)
34
- - [Installation](#installation)
35
- - [Quick Start](#quick-start)
36
- - [Interfaces](#interfaces)
37
- - [Bus (immediate processing)](#bus-immediate-processing)
38
- - [Station (background processing)](#station-background-processing)
39
- - [Advanced Usage & Considerations](#advanced-usage--considerations)
40
- - [Concurrency Controls](#concurrency-controls)
41
- - [Bus Interface (Async)](#bus-interface-async)
42
- - [Station Interface (Thread Pool)](#station-interface-thread-pool)
43
- - [Error Handling & Recovery](#error-handling--recovery)
44
- - [Memory Considerations](#memory-considerations)
45
- - [Blocking Operations](#blocking-operations)
46
- - [Shutdown & Cleanup](#shutdown--cleanup)
47
- - [Limitations](#limitations)
48
- - [Sponsors](#sponsors)
33
+ - [Why LocalBus?](#why-localbus)
34
+ - [Installation](#installation)
35
+ - [Quick Start](#quick-start)
36
+ - [Interfaces](#interfaces)
37
+ - [Bus (immediate processing)](#bus-immediate-processing)
38
+ - [Station (background processing)](#station-background-processing)
39
+ - [Advanced Usage & Considerations](#advanced-usage--considerations)
40
+ - [Concurrency Controls](#concurrency-controls)
41
+ - [Bus Interface (Async)](#bus-interface-async)
42
+ - [Station Interface (Thread Pool)](#station-interface-thread-pool)
43
+ - [Error Handling & Recovery](#error-handling--recovery)
44
+ - [Memory Considerations](#memory-considerations)
45
+ - [Blocking Operations](#blocking-operations)
46
+ - [Shutdown & Cleanup](#shutdown--cleanup)
47
+ - [Limitations](#limitations)
48
+ - [See Also](#see-also)
49
+ - [Sponsors](#sponsors)
49
50
 
50
51
  <!-- Tocer[finish]: Auto-generated, don't remove. -->
51
52
 
@@ -184,7 +185,7 @@ The Bus interface uses Async's Semaphore to limit resource consumption:
184
185
 
185
186
  ```ruby
186
187
  # Configure concurrency limits for the Bus
187
- bus = LocalBus::Bus.new(concurrency_limit: 10)
188
+ bus = LocalBus::Bus.new(max_concurrency: 10)
188
189
 
189
190
  # The semaphore ensures only N concurrent operations run at once
190
191
  bus.subscribe "resource.intensive" do |message|
@@ -193,7 +194,7 @@ bus.subscribe "resource.intensive" do |message|
193
194
  end
194
195
  ```
195
196
 
196
- When the concurrency limit is reached, new publish operations will wait until a slot becomes available. This prevents memory bloat but means you should be mindful of timeouts in your subscribers.
197
+ When the max concurrency limit is reached, new publish operations will wait until a slot becomes available. This prevents memory bloat but means you should be mindful of timeouts in your subscribers.
197
198
 
198
199
  #### Station Interface (Thread Pool)
199
200
 
@@ -203,7 +204,7 @@ The Station interface uses Concurrent Ruby's fixed thread pool with a fallback p
203
204
  # Configure the thread pool size for the Station
204
205
  station = LocalBus::Station.new(
205
206
  max_queue: 5_000, # Maximum number of queued items
206
- threads: 10, # Maximum pool size
207
+ max_threads: 10, # Maximum pool size
207
208
  fallback_policy: :caller_runs # Runs on calling thread
208
209
  )
209
210
  ```
@@ -275,7 +276,7 @@ For example, idempotency _(i.e. messages that can be re-published without uninte
275
276
 
276
277
  - The Bus interface is single-threaded - long-running subscribers can impact latency
277
278
  - The Station interface may drop messages if configured with `:discard` fallback policy
278
- - No persistence - pending messages are lost on process restart
279
+ - No persistence - pending messages may be lost on process restart
279
280
  - No distributed support - communication limited to single process
280
281
  - Large payloads can impact memory usage, especially under high load
281
282
  - No built-in retry mechanism for failed subscribers
data/lib/local_bus/bus.rb CHANGED
@@ -8,27 +8,27 @@ class LocalBus
8
8
  include MonitorMixin
9
9
 
10
10
  # Constructor
11
- # @note Creates a new Bus instance with specified concurrency
12
- # @rbs concurrency: Integer -- maximum number of concurrent tasks (default: Concurrent.processor_count)
13
- def initialize(concurrency: Concurrent.processor_count)
11
+ # @note Creates a new Bus instance with specified max concurrency (i.e. number of tasks that can run in parallel)
12
+ # @rbs max_concurrency: Integer -- maximum number of concurrent tasks (default: Concurrent.processor_count)
13
+ def initialize(max_concurrency: Concurrent.processor_count)
14
14
  super()
15
- @concurrency = concurrency.to_i
15
+ @max_concurrency = max_concurrency.to_i
16
16
  @subscriptions = Concurrent::Hash.new do |hash, key|
17
17
  hash[key] = Concurrent::Set.new
18
18
  end
19
19
  end
20
20
 
21
21
  # Maximum number of concurrent tasks that can run in "parallel"
22
- # @rbs return: Integer -- current concurrency value
23
- def concurrency
24
- synchronize { @concurrency }
22
+ # @rbs return: Integer
23
+ def max_concurrency
24
+ synchronize { @max_concurrency }
25
25
  end
26
26
 
27
- # Sets the concurrency
28
- # @rbs concurrency: Integer -- max number of concurrent tasks that can run in "parallel"
27
+ # Sets the max concurrency
28
+ # @rbs value: Integer -- max number of concurrent tasks that can run in "parallel"
29
29
  # @rbs return: Integer -- new concurrency value
30
- def concurrency=(value)
31
- synchronize { @concurrency = value.to_i }
30
+ def max_concurrency=(value)
31
+ synchronize { @max_concurrency = value.to_i }
32
32
  end
33
33
 
34
34
  # Registered topics that have subscribers
@@ -112,7 +112,7 @@ class LocalBus
112
112
  if subscribers.any?
113
113
  Sync do |task|
114
114
  task.with_timeout timeout.to_f do
115
- semaphore = Async::Semaphore.new(concurrency, parent: barrier)
115
+ semaphore = Async::Semaphore.new(max_concurrency, parent: barrier)
116
116
 
117
117
  subscribers.each do |subscriber|
118
118
  semaphore.async do
@@ -33,21 +33,21 @@ class LocalBus
33
33
 
34
34
  # Constructor
35
35
  # @rbs bus: Bus -- local message bus (default: Bus.new)
36
- # @rbs threads: Integer -- number of threads (default: Concurrent.processor_count)
36
+ # @rbs max_threads: Integer -- number of max_threads (default: Concurrent.processor_count)
37
37
  # @rbs default_timeout: Float -- seconds to wait for a future to complete
38
38
  # @rbs shutdown_timeout: Float -- seconds to wait for all futures to complete on process exit
39
39
  # @rbs options: Hash[Symbol, untyped] -- Concurrent::FixedThreadPool options
40
40
  # @rbs return: void
41
41
  def initialize(
42
42
  bus: Bus.new,
43
- threads: Concurrent.processor_count,
43
+ max_threads: Concurrent.processor_count,
44
44
  default_timeout: 0,
45
45
  shutdown_timeout: 8,
46
46
  **options
47
47
  )
48
48
  super()
49
49
  @bus = bus
50
- @threads = [2, threads].max.to_i
50
+ @max_threads = [2, max_threads].max.to_i
51
51
  @default_timeout = default_timeout.to_f
52
52
  @shutdown_timeout = shutdown_timeout.to_f
53
53
  @shutdown = Concurrent::AtomicBoolean.new(false)
@@ -60,7 +60,7 @@ class LocalBus
60
60
 
61
61
  # Number of threads used to process messages
62
62
  # @rbs return: Integer
63
- attr_reader :threads
63
+ attr_reader :max_threads
64
64
 
65
65
  # Default timeout for message processing (in seconds)
66
66
  # @rbs return: Float
@@ -78,7 +78,7 @@ class LocalBus
78
78
  return if running?
79
79
 
80
80
  start_shutdown_handler
81
- @pool = Concurrent::FixedThreadPool.new(threads, THREAD_POOL_OPTIONS.merge(options))
81
+ @pool = Concurrent::FixedThreadPool.new(max_threads, THREAD_POOL_OPTIONS.merge(options))
82
82
  enable_safe_shutdown on: ["HUP", "INT", "QUIT", "TERM"]
83
83
  end
84
84
  end
@@ -3,5 +3,5 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  class LocalBus
6
- VERSION = "0.1.2"
6
+ VERSION = "0.2.0"
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: local_bus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Hopkins (hopsoft)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-05 00:00:00.000000000 Z
11
+ date: 2024-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async