omq-ractor 0.1.5 → 0.1.8

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 +3 -3
  3. data/lib/omq/ractor.rb +21 -17
  4. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b37fbceaf8b22765e84ec6f0ee63d5fb290e227d88c5abab8d0f85f6169d028b
4
- data.tar.gz: 5e75dccb8bdd313ae0cb1c25e79b9a10d9e13decb98d6ad042babebbcdea7437
3
+ metadata.gz: fc8588dc4362b294801c75c4c34f494bf9f5958fc4c772464ed0ed3f4000e1ad
4
+ data.tar.gz: d35730efb57a69a74df32763a70f6a94b22eda3db681408b6f9407ddcab398de
5
5
  SHA512:
6
- metadata.gz: d2d2de879b721455d8d8f2e826f8c4de9e524f3a3f152fda0eee0b31410a0b9b7d2ec42d340288082e57647b1948789eb98aaa6138a177ea373e33b229f9190f
7
- data.tar.gz: 2baa73f333c9600f9215ac3e49aea2de1149ea89786be62b8699b851000304f7b00078075026099bf1ec9074546d688027e3ae977e9ff6ce68b2a549894b8874
6
+ metadata.gz: 8ddedd9fac719c1b7ccffbc29931bf7647139c69dc965844f09eb526601f9c2a7501b635ce3381ccae81e1b4d137cc758e9345cd98ba1c037dae6ea7b30447ac
7
+ data.tar.gz: 56f0e7e5795151c47a0363341831c4e6a6e6d6450b5e51fb5302865d0d0d64dd28ee05428acecf40db00e8e7ac916392bf6b18347550d12ed910483fb907b800
data/README.md CHANGED
@@ -1,6 +1,6 @@
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)
3
+ [![CI](https://github.com/zeromq/omq.rb/actions/workflows/ci.yml/badge.svg)](https://github.com/zeromq/omq.rb/actions/workflows/ci.yml)
4
4
  [![Gem Version](https://img.shields.io/gem/v/omq-ractor?color=e9573f)](https://rubygems.org/gems/omq-ractor)
5
5
  [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
6
6
  [![Ruby](https://img.shields.io/badge/Ruby-%3E%3D%204.0-CC342D?logo=ruby&logoColor=white)](https://www.ruby-lang.org)
@@ -119,7 +119,7 @@ end
119
119
  ```
120
120
 
121
121
  Topic prefix matching works normally. The topic stays as a plain string
122
- frame; only the payload is serialized.
122
+ frame. Only the payload is serialized.
123
123
 
124
124
  ### Worker pool
125
125
 
@@ -215,7 +215,7 @@ a Reactor.run round-trip per message.
215
215
  Setup handshake: the worker must call `omq.sockets` as its first
216
216
  action. This creates worker-owned input ports, sends them to the main
217
217
  Ractor, and returns SocketProxy objects. The main Ractor waits up to
218
- 100ms; if the handshake doesn't complete, the Ractor is stopped and
218
+ 100ms. If the handshake doesn't complete, the Ractor is stopped and
219
219
  an error is raised.
220
220
 
221
221
 
data/lib/omq/ractor.rb CHANGED
@@ -31,7 +31,7 @@ module OMQ
31
31
  #
32
32
  class Ractor
33
33
 
34
- HANDSHAKE_TIMEOUT = 5
34
+ HANDSHAKE_TIMEOUT = 1
35
35
 
36
36
 
37
37
  # Socket types that use topic/group-based routing.
@@ -43,7 +43,7 @@ module OMQ
43
43
  # -- Connection wrappers -------------------------------------------
44
44
 
45
45
  # Mixed into all connection wrappers so is_a? checks against
46
- # the wrapped class (e.g. DirectPipe) still work.
46
+ # the wrapped class (e.g. Pipe) still work.
47
47
  #
48
48
  module TransparentDelegator
49
49
  # @param klass [Class] class to check against
@@ -121,7 +121,7 @@ module OMQ
121
121
  end
122
122
 
123
123
 
124
- # Wraps an inproc DirectPipe with Ractor.make_shareable.
124
+ # Wraps an inproc Pipe with Ractor.make_shareable.
125
125
  #
126
126
  class ShareableConnection < SimpleDelegator
127
127
  include TransparentDelegator
@@ -398,6 +398,14 @@ module OMQ
398
398
  serialize: serialize, topic_type: topic_type }
399
399
  end
400
400
 
401
+ # REQ/REP input bridges must wait for the matching send before reading
402
+ # again. REP starts with a receive; REQ starts with a send.
403
+ @receive_permits = sockets.map do |socket|
404
+ next unless socket.is_a?(REQ) || socket.is_a?(REP)
405
+
406
+ Async::Queue.new.tap { |queue| queue.enqueue(true) if socket.is_a?(REP) }
407
+ end
408
+
401
409
 
402
410
  # Main Ractor creates output ports (one per writable socket)
403
411
  @output_ports = socket_configs.map { |cfg| cfg[:writable] ? ::Ractor::Port.new : nil }
@@ -525,10 +533,10 @@ module OMQ
525
533
  @sockets.each_with_index do |socket, i|
526
534
  cache = SerializeCache.new
527
535
  topic_type = socket_configs[i][:topic_type]
528
- engine = socket.instance_variable_get(:@engine)
536
+ engine = socket.engine
529
537
 
530
538
  engine.connection_wrapper = ->(conn) do
531
- inproc = conn.is_a?(Transport::Inproc::DirectPipe)
539
+ inproc = conn.is_a?(Transport::Inproc::Pipe)
532
540
  if topic_type
533
541
  inproc ? TopicShareableConnection.new(conn) : TopicMarshalConnection.new(conn, cache)
534
542
  else
@@ -548,9 +556,11 @@ module OMQ
548
556
 
549
557
  do_serialize = socket_configs[i][:serialize]
550
558
  topic_type = socket_configs[i][:topic_type]
559
+ permit = @receive_permits[i]
551
560
 
552
561
  @input_tasks << @parent_task.async(transient: true, annotation: "ractor input bridge") do
553
562
  loop do
563
+ permit&.dequeue
554
564
  msg = socket.receive
555
565
  if do_serialize && !topic_type
556
566
  msg = msg.first
@@ -579,11 +589,9 @@ module OMQ
579
589
  port = output_ports[i]
580
590
  next unless port
581
591
 
582
- do_serialize = socket_configs[i][:serialize]
583
- topic_type = socket_configs[i][:topic_type]
584
- engine = socket.instance_variable_get(:@engine)
585
- queue = Thread::Queue.new
586
- rd, wr = IO.pipe
592
+ engine = socket.engine
593
+ queue = Thread::Queue.new
594
+ rd, wr = IO.pipe
587
595
  @output_pipes << rd << wr
588
596
 
589
597
  # Thread: port.receive -> queue + pipe signal
@@ -607,13 +615,9 @@ module OMQ
607
615
  rd.read_nonblock(4096) rescue nil
608
616
 
609
617
  while (msg = queue.pop(true) rescue nil)
610
- if do_serialize
611
- parts = topic_type && msg.is_a?(Array) ? msg : [msg]
612
- engine.enqueue_send(parts)
613
- else
614
- parts = socket.__send__(:freeze_message, msg)
615
- engine.enqueue_send(parts)
616
- end
618
+ parts = msg.is_a?(Array) ? msg : [msg]
619
+ engine.enqueue_send(parts)
620
+ @receive_permits[i]&.enqueue(true)
617
621
  end
618
622
  rescue IOError, Async::Stop
619
623
  break
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.5
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
@@ -13,16 +13,16 @@ dependencies:
13
13
  name: omq
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
16
+ - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '0.19'
18
+ version: '0.28'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - ">="
23
+ - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '0.19'
25
+ version: '0.28'
26
26
  email:
27
27
  - paddor@gmail.com
28
28
  executables: []
@@ -33,7 +33,7 @@ files:
33
33
  - README.md
34
34
  - lib/omq-ractor.rb
35
35
  - lib/omq/ractor.rb
36
- homepage: https://github.com/paddor/omq-ractor
36
+ homepage: https://github.com/zeromq/omq.rb/tree/main/gems/omq-ractor
37
37
  licenses:
38
38
  - ISC
39
39
  metadata: {}
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0'
53
53
  requirements: []
54
- rubygems_version: 4.0.6
54
+ rubygems_version: 4.0.20
55
55
  specification_version: 4
56
56
  summary: Bridge OMQ sockets into Ruby Ractors for true parallel processing
57
57
  test_files: []