omq-ractor 0.1.1 → 0.1.2

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/README.md +26 -11
  3. data/lib/omq/ractor.rb +29 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08afc746c52ec650ff7913ac2c58f164b206c547902539949ae2ac1c3e727e45'
4
- data.tar.gz: e3ef4264d010e074fabc0076f3ff8fe5f743e940fd07b389b4ab4f84b8db0e17
3
+ metadata.gz: 15931abc881035b0cac7d80667168cd3dbdd120226178b76725d2fa40260ac5f
4
+ data.tar.gz: 82c4e9531bb7afc5e471d435fadb068b0e7cbf92b9a8db70a063c7623a9cb5bc
5
5
  SHA512:
6
- metadata.gz: 9585c7fc0a48b60f5daf61629ba32850945ee8fd07799b6e09e6f4c35810d13950f67a8c1f08ab7ff42c041c93e6225d176755b91a329c120b1dcba6d461f746
7
- data.tar.gz: 8a9295ef54bf9edc729d2e0c47593b8cdf11cc10cfb46bba1f8b004bcd28c89f9b809f3ab9577ef12ef75822773a0db44046a2ed751317278146b3c292ba3194
6
+ metadata.gz: 41ebd53843bb6e69859a6546bc1d6f7926f8e03894c10de1bffdbd2a6d294e282bc1b8c04d735920178ea4b25bdd509d5822fee1979121dc6b307224150785fb
7
+ data.tar.gz: 7f490382cb90a176d28a1d67e75f4edd5f53b2e10740366d81d49c0f5e73b21e63284ae084b1eb7616a9f54d609d64cc42b2e3ff39738f57e035293f6e8d6963
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # OMQ::Ractor -- Networked Ractors
2
2
 
3
+ [![CI](https://github.com/paddor/omq-ractor/actions/workflows/ci.yml/badge.svg)](https://github.com/paddor/omq-ractor/actions/workflows/ci.yml)
4
+ [![Gem Version](https://img.shields.io/gem/v/omq-ractor?color=e9573f)](https://rubygems.org/gems/omq-ractor)
5
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
6
+ [![Ruby](https://img.shields.io/badge/Ruby-%3E%3D%204.0-CC342D?logo=ruby&logoColor=white)](https://www.ruby-lang.org)
7
+
3
8
  Ruby Ractors give you true parallelism -- each Ractor gets its own GVL,
4
9
  so CPU-bound work runs on separate cores. But they can only talk to each
5
10
  other inside a single process, using `Ractor::Port`. No networking, no
@@ -45,8 +50,7 @@ Async do
45
50
  worker = OMQ::Ractor.new(pull, push) do |omq|
46
51
  pull_p, push_p = omq.sockets # handshake (must be first call)
47
52
 
48
- loop do
49
- msg = pull_p.receive
53
+ while msg = pull_p.receive # nil on close
50
54
  push_p << expensive_transform(msg)
51
55
  end
52
56
  end
@@ -61,25 +65,36 @@ lightweight wrappers around `Ractor::Port` pairs.
61
65
 
62
66
  ### Multiplexing with Ractor.select
63
67
 
68
+ `Ractor.select` waits on multiple `Ractor::Port` objects and returns
69
+ `[port, value]`. Use `#to_port` to get the underlying port, and
70
+ `#socket_for` to map back to the proxy:
71
+
64
72
  ```ruby
65
73
  worker = OMQ::Ractor.new(pull_a, pull_b, push) do |omq|
66
- a, b, out = omq.sockets
74
+ sockets = omq.sockets
75
+ a, b, out = sockets
67
76
 
68
77
  loop do
69
- source, msg = Ractor.select(a.to_port, b.to_port)
70
- out << process(msg)
78
+ port, msg = Ractor.select(a.to_port, b.to_port)
79
+ break if msg.nil? # socket closed
80
+ source = sockets.socket_for(port) # => a or b
81
+ out << process(source, msg)
71
82
  end
72
83
  end
73
84
  ```
74
85
 
86
+ Note: `Ractor.select` returns raw port values, bypassing `SocketProxy#receive`.
87
+ For topic-based sockets, `msg` will be the full `[topic, payload]` array --
88
+ use `#receive` or `#receive_with_topic` on a single proxy instead if you
89
+ need topic stripping.
90
+
75
91
  ### Bidirectional (PAIR, REQ/REP, DEALER)
76
92
 
77
93
  ```ruby
78
94
  worker = OMQ::Ractor.new(pair) do |omq|
79
95
  p = omq.sockets.first
80
96
 
81
- loop do
82
- msg = p.receive
97
+ while msg = p.receive
83
98
  p << transform(msg)
84
99
  end
85
100
  end
@@ -122,8 +137,7 @@ Async do
122
137
 
123
138
  OMQ::Ractor.new(pull, push) do |omq|
124
139
  p_in, p_out = omq.sockets
125
- loop do
126
- msg = p_in.receive
140
+ while msg = p_in.receive
127
141
  p_out << expensive_transform(msg)
128
142
  end
129
143
  end
@@ -160,8 +174,9 @@ Use `serialize: false` for raw messages (frozen string arrays):
160
174
  ```ruby
161
175
  worker = OMQ::Ractor.new(pull, push, serialize: false) do |omq|
162
176
  p_in, p_out = omq.sockets
163
- msg = p_in.receive # frozen string array, e.g. ["hello"]
164
- p_out << [msg.first.upcase] # must send frozen string arrays
177
+ while msg = p_in.receive # frozen string array, e.g. ["hello"]
178
+ p_out << [msg.first.upcase] # must send frozen string arrays
179
+ end
165
180
  end
166
181
  ```
167
182
 
data/lib/omq/ractor.rb CHANGED
@@ -230,6 +230,33 @@ module OMQ
230
230
  end
231
231
 
232
232
 
233
+ # Array of SocketProxy objects with a port→proxy lookup for
234
+ # Ractor.select results.
235
+ #
236
+ class SocketSet < Array
237
+ def initialize(proxies)
238
+ super(proxies)
239
+ @by_port = {}
240
+ proxies.each do |proxy|
241
+ @by_port[proxy.to_port] = proxy if proxy.to_port rescue nil
242
+ end
243
+ end
244
+
245
+ # Returns the SocketProxy whose input port matches +port+.
246
+ # Use after Ractor.select to map back to the proxy:
247
+ #
248
+ # port, msg = Ractor.select(a.to_port, b.to_port)
249
+ # source = sockets.socket_for(port)
250
+ #
251
+ # @param port [Ractor::Port]
252
+ # @return [SocketProxy, nil]
253
+ #
254
+ def socket_for(port)
255
+ @by_port[port]
256
+ end
257
+ end
258
+
259
+
233
260
  # -- Context -------------------------------------------------------
234
261
 
235
262
  # Frozen, shareable context passed to the worker Ractor.
@@ -252,9 +279,10 @@ module OMQ
252
279
 
253
280
  @setup_port.send(input_ports)
254
281
 
255
- @socket_configs.each_with_index.map do |cfg, i|
282
+ proxies = @socket_configs.each_with_index.map do |cfg, i|
256
283
  SocketProxy.new(input_ports[i], @output_ports[i], cfg[:topic_type])
257
284
  end
285
+ SocketSet.new(proxies)
258
286
  end
259
287
  end
260
288
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omq-ractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger