ori-rb 0.4.7 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +62 -0
- data/lib/ori/broadcast.rb +79 -0
- data/lib/ori/scope.rb +2 -2
- data/lib/ori/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 275fec2a2a0a918b10e34443cd062b7d70bdbedabb55d4b6ecb33de40c4ab20a
|
|
4
|
+
data.tar.gz: d17b29ea758c370e790feded2cd97000a7d8d2b63f58a4157b2a1cff6b59d3a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41975ccf93c63dc710021d5fc9823e293af37197ef9d163aa369236c0f4f9948ea8c28aba679cbdcd1176d3caffd00ed662f80f38c32521f7e020e5b390a99f4
|
|
7
|
+
data.tar.gz: e9000159fddf3054c49096a3e885a16df864e405348c97d4a74f6305ddd25c0a46d01e15fda81bb5026c1e3f288e5b1c5f00bc0a4b552f72aee8c9ad44524451
|
data/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Ori provides a set of primitives that allow you to build concurrent applications
|
|
|
19
19
|
- [`Ori::Mutex`](#orimutex)
|
|
20
20
|
- [`Ori::Semaphore`](#orisemaphore)
|
|
21
21
|
- [`Ori::Timeout`](#oritimeout)
|
|
22
|
+
- [`Ori::Broadcast`](#oribroadcast)
|
|
22
23
|
- [Releases](#releases)
|
|
23
24
|
- [License](#license)
|
|
24
25
|
|
|
@@ -428,6 +429,67 @@ Timeout!
|
|
|
428
429
|
|
|
429
430
|
</details>
|
|
430
431
|
|
|
432
|
+
#### `Ori::Broadcast`
|
|
433
|
+
|
|
434
|
+
Broadcast provides fan-out message delivery to multiple subscribers. Unlike a `Channel`, where each message is consumed by a single reader, every subscriber to a `Broadcast` receives every message published after they subscribe:
|
|
435
|
+
|
|
436
|
+
```ruby
|
|
437
|
+
Ori.sync do |scope|
|
|
438
|
+
broadcast = Ori::Broadcast.new
|
|
439
|
+
sub1 = broadcast.subscribe
|
|
440
|
+
sub2 = broadcast.subscribe
|
|
441
|
+
|
|
442
|
+
# Publisher
|
|
443
|
+
scope.fork do
|
|
444
|
+
broadcast << "Hello"
|
|
445
|
+
broadcast << "World"
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Both subscribers receive all messages
|
|
449
|
+
scope.fork do
|
|
450
|
+
2.times { puts "Sub 1: #{sub1.take}" }
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
scope.fork do
|
|
454
|
+
2.times { puts "Sub 2: #{sub2.take}" }
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Output:**
|
|
460
|
+
|
|
461
|
+
```
|
|
462
|
+
Sub 1: Hello
|
|
463
|
+
Sub 2: Hello
|
|
464
|
+
Sub 1: World
|
|
465
|
+
Sub 2: World
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Subscriptions work with `Ori.select` and pattern matching:
|
|
469
|
+
|
|
470
|
+
```ruby
|
|
471
|
+
Ori.sync do |scope|
|
|
472
|
+
broadcast = Ori::Broadcast.new
|
|
473
|
+
sub = broadcast.subscribe
|
|
474
|
+
timeout = Ori::Timeout.new(0.5)
|
|
475
|
+
|
|
476
|
+
scope.fork { broadcast << :event }
|
|
477
|
+
|
|
478
|
+
case Ori.select([sub, timeout])
|
|
479
|
+
in Ori::Broadcast::Subscription(value) then puts "Got: #{value}"
|
|
480
|
+
in Ori::Timeout then puts "No events"
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Subscribers can unsubscribe at any time to stop receiving future messages:
|
|
486
|
+
|
|
487
|
+
```ruby
|
|
488
|
+
sub = broadcast.subscribe
|
|
489
|
+
# ...
|
|
490
|
+
sub.unsubscribe
|
|
491
|
+
```
|
|
492
|
+
|
|
431
493
|
## Releases
|
|
432
494
|
|
|
433
495
|
The procedure to publish a new release version is as follows:
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
module Ori
|
|
4
|
+
#: [E]
|
|
5
|
+
class Broadcast
|
|
6
|
+
def initialize
|
|
7
|
+
@subscriptions = [] #: Array[Subscription[E]]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
#: () -> Subscription[E]
|
|
11
|
+
def subscribe
|
|
12
|
+
subscription = Subscription.new(self)
|
|
13
|
+
@subscriptions << subscription
|
|
14
|
+
subscription
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#: (Subscription[E] subscription) -> void
|
|
18
|
+
def unsubscribe(subscription)
|
|
19
|
+
@subscriptions.delete(subscription)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#: (E item) -> void
|
|
23
|
+
def publish(item)
|
|
24
|
+
@subscriptions.each { |sub| sub.__send_item(item) }
|
|
25
|
+
end
|
|
26
|
+
alias_method(:<<, :publish)
|
|
27
|
+
|
|
28
|
+
#: [E]
|
|
29
|
+
class Subscription
|
|
30
|
+
include(Ori::Selectable)
|
|
31
|
+
|
|
32
|
+
#: (Broadcast[E] broadcast) -> void
|
|
33
|
+
def initialize(broadcast)
|
|
34
|
+
@broadcast = broadcast
|
|
35
|
+
@queue = [] #: Array[E]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#: () -> E
|
|
39
|
+
def take
|
|
40
|
+
Fiber.yield(self) until value?
|
|
41
|
+
@queue.shift #: as E
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#: () -> E
|
|
45
|
+
def peek
|
|
46
|
+
Fiber.yield(self) until value?
|
|
47
|
+
@queue.first #: as E
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#: () -> bool
|
|
51
|
+
def value?
|
|
52
|
+
!@queue.empty?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#: () -> Subscription[E]
|
|
56
|
+
def await
|
|
57
|
+
peek
|
|
58
|
+
self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#: () -> Array[E]
|
|
62
|
+
def deconstruct
|
|
63
|
+
Ori.sync { peek }
|
|
64
|
+
[take]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#: () -> void
|
|
68
|
+
def unsubscribe
|
|
69
|
+
@broadcast.unsubscribe(self)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @api private
|
|
73
|
+
#: (E item) -> void
|
|
74
|
+
def __send_item(item)
|
|
75
|
+
@queue << item
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/ori/scope.rb
CHANGED
|
@@ -457,7 +457,7 @@ module Ori
|
|
|
457
457
|
# TODO: shuffle blocked before processing?
|
|
458
458
|
blocked.each do |fiber, resource|
|
|
459
459
|
case resource
|
|
460
|
-
when Ori::Channel
|
|
460
|
+
when Ori::Channel, Ori::Broadcast::Subscription
|
|
461
461
|
fibers_to_resume << fiber if resource.value?
|
|
462
462
|
when Ori::Promise
|
|
463
463
|
fibers_to_resume << fiber if resource.resolved?
|
|
@@ -621,7 +621,7 @@ module Ori
|
|
|
621
621
|
when CancellationError
|
|
622
622
|
@tracer&.record(id, :cancelled, result.message)
|
|
623
623
|
task_or_fiber.kill
|
|
624
|
-
when Ori::Channel, Ori::Promise, Ori::Semaphore, Ori::ReentrantSemaphore
|
|
624
|
+
when Ori::Channel, Ori::Promise, Ori::Semaphore, Ori::ReentrantSemaphore, Ori::Broadcast::Subscription
|
|
625
625
|
@tracer&.record(id, :resource_wait, result.class.name)
|
|
626
626
|
blocked[fiber] = result
|
|
627
627
|
when Task
|
data/lib/ori/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ori-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jahfer Husain
|
|
@@ -63,6 +63,7 @@ files:
|
|
|
63
63
|
- docs/images/example_trace.png
|
|
64
64
|
- docs/images/example_trace_tag.png
|
|
65
65
|
- lib/ori.rb
|
|
66
|
+
- lib/ori/broadcast.rb
|
|
66
67
|
- lib/ori/channel.rb
|
|
67
68
|
- lib/ori/lazy.rb
|
|
68
69
|
- lib/ori/mutex.rb
|