fiber_stream 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +87 -56
- data/examples/README.md +6 -0
- data/examples/ractor_producer_sources.rb +43 -0
- data/lib/fiber_stream/flow.rb +40 -17
- data/lib/fiber_stream/internal/ractor_transfer_policy.rb +17 -0
- data/lib/fiber_stream/pipeline.rb +5 -1
- data/lib/fiber_stream/pull/parallel_unordered_map_boundary.rb +311 -0
- data/lib/fiber_stream/pull/ractor_map_boundary.rb +50 -51
- data/lib/fiber_stream/pull/ractor_merge_ports_source.rb +18 -3
- data/lib/fiber_stream/pull/ractor_port_source.rb +39 -6
- data/lib/fiber_stream/pull/ractor_producer_source.rb +349 -0
- data/lib/fiber_stream/pull/scan.rb +38 -0
- data/lib/fiber_stream/pull.rb +54 -5
- data/lib/fiber_stream/ractor_producer.rb +167 -0
- data/lib/fiber_stream/running_pipeline.rb +4 -0
- data/lib/fiber_stream/sink.rb +9 -19
- data/lib/fiber_stream/source.rb +78 -22
- data/lib/fiber_stream/version.rb +1 -1
- data/lib/fiber_stream.rb +2 -0
- data/sig/fiber_stream.rbs +18 -1
- metadata +9 -3
data/lib/fiber_stream/sink.rb
CHANGED
|
@@ -10,10 +10,7 @@ module FiberStream
|
|
|
10
10
|
new do |stream|
|
|
11
11
|
values = []
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
value = stream.next
|
|
15
|
-
break if Pull.done?(value)
|
|
16
|
-
|
|
13
|
+
Pull.each_value(stream) do |value|
|
|
17
14
|
values << value
|
|
18
15
|
end
|
|
19
16
|
|
|
@@ -45,10 +42,7 @@ module FiberStream
|
|
|
45
42
|
new do |stream|
|
|
46
43
|
accumulator = initial
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
value = stream.next
|
|
50
|
-
break if Pull.done?(value)
|
|
51
|
-
|
|
45
|
+
Pull.each_value(stream) do |value|
|
|
52
46
|
accumulator = block.call(accumulator, value)
|
|
53
47
|
end
|
|
54
48
|
|
|
@@ -68,10 +62,7 @@ module FiberStream
|
|
|
68
62
|
new do |stream|
|
|
69
63
|
count = 0
|
|
70
64
|
|
|
71
|
-
|
|
72
|
-
value = stream.next
|
|
73
|
-
break if Pull.done?(value)
|
|
74
|
-
|
|
65
|
+
Pull.each_value(stream) do |value|
|
|
75
66
|
block.call(value)
|
|
76
67
|
count += 1
|
|
77
68
|
end
|
|
@@ -99,15 +90,17 @@ module FiberStream
|
|
|
99
90
|
end
|
|
100
91
|
end
|
|
101
92
|
|
|
93
|
+
def self.build(&run) # :nodoc:
|
|
94
|
+
new(&run)
|
|
95
|
+
end
|
|
96
|
+
|
|
102
97
|
def initialize(&run)
|
|
103
98
|
@run = run
|
|
104
99
|
end
|
|
105
100
|
|
|
106
101
|
private_class_method :new
|
|
107
102
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def run(stream)
|
|
103
|
+
def run_stream(stream) # :nodoc:
|
|
111
104
|
@run.call(stream)
|
|
112
105
|
end
|
|
113
106
|
|
|
@@ -121,10 +114,7 @@ module FiberStream
|
|
|
121
114
|
end
|
|
122
115
|
|
|
123
116
|
def run(stream)
|
|
124
|
-
|
|
125
|
-
value = stream.next
|
|
126
|
-
break if Pull.done?(value)
|
|
127
|
-
|
|
117
|
+
Pull.each_value(stream) do |value|
|
|
128
118
|
write(value)
|
|
129
119
|
end
|
|
130
120
|
|
data/lib/fiber_stream/source.rb
CHANGED
|
@@ -47,7 +47,7 @@ module FiberStream
|
|
|
47
47
|
raise TypeError, "ack_port must provide Ractor-style send"
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Internal::RactorTransferPolicy.validate!(:ack_transfer, ack_transfer)
|
|
51
51
|
raise TypeError, "cancel must be true or false" unless [true, false].include?(cancel)
|
|
52
52
|
|
|
53
53
|
new(-> { Pull.ractor_port(port, ack_port, ack_transfer, cancel) })
|
|
@@ -65,12 +65,56 @@ module FiberStream
|
|
|
65
65
|
def self.ractor_merge_ports(ports, ack_transfer: :copy, cancel: true)
|
|
66
66
|
pairs = normalize_ractor_merge_port_pairs(ports)
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
Internal::RactorTransferPolicy.validate!(:ack_transfer, ack_transfer)
|
|
69
69
|
raise TypeError, "cancel must be true or false" unless [true, false].include?(cancel)
|
|
70
70
|
|
|
71
71
|
new(-> { Pull.ractor_merge_ports(pairs, ack_transfer, cancel) })
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
+
# Creates a source backed by one FiberStream-owned producer ractor.
|
|
75
|
+
#
|
|
76
|
+
# The producer ractor is started lazily on first downstream demand. The
|
|
77
|
+
# shareable block receives a `RactorProducer` context and the provided
|
|
78
|
+
# arguments. Calls to the context preserve one-outstanding-ack
|
|
79
|
+
# backpressure, and cleanup always requests cooperative cancellation.
|
|
80
|
+
def self.ractor_producer(*args, transfer: :copy, ack_transfer: :copy, &block)
|
|
81
|
+
raise ArgumentError, "missing block" unless block
|
|
82
|
+
|
|
83
|
+
Internal::RactorTransferPolicy.validate!(:transfer, transfer)
|
|
84
|
+
Internal::RactorTransferPolicy.validate!(:ack_transfer, ack_transfer)
|
|
85
|
+
raise TypeError, "block must be shareable" unless Ractor.shareable?(block)
|
|
86
|
+
|
|
87
|
+
group = RactorProducerGroup.new(transfer)
|
|
88
|
+
group.producer(*args, &block)
|
|
89
|
+
definitions = group.definitions
|
|
90
|
+
|
|
91
|
+
new(-> { Pull.ractor_producer(definitions, ack_transfer) })
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Creates a source backed by multiple FiberStream-owned producer ractors.
|
|
95
|
+
#
|
|
96
|
+
# The registration block runs at construction to collect producer
|
|
97
|
+
# definitions, but producer ractors and ports are started lazily on first
|
|
98
|
+
# downstream demand. Outputs are merged with the same ready-order semantics
|
|
99
|
+
# as `Source.ractor_merge_ports`.
|
|
100
|
+
def self.ractor_merge_producers(transfer: :copy, ack_transfer: :copy, &block)
|
|
101
|
+
raise ArgumentError, "missing block" unless block
|
|
102
|
+
|
|
103
|
+
Internal::RactorTransferPolicy.validate!(:transfer, transfer)
|
|
104
|
+
Internal::RactorTransferPolicy.validate!(:ack_transfer, ack_transfer)
|
|
105
|
+
|
|
106
|
+
group = RactorProducerGroup.new(transfer)
|
|
107
|
+
block.call(group)
|
|
108
|
+
definitions = group.definitions
|
|
109
|
+
raise ArgumentError, "ractor_merge_producers requires at least two producers" if definitions.size < 2
|
|
110
|
+
|
|
111
|
+
new(-> { Pull.ractor_merge_producers(definitions, ack_transfer) })
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def self.build(source_factory, flows = []) # :nodoc:
|
|
115
|
+
new(source_factory, flows)
|
|
116
|
+
end
|
|
117
|
+
|
|
74
118
|
def initialize(source_factory, flows = [])
|
|
75
119
|
@source_factory = source_factory
|
|
76
120
|
@flows = flows
|
|
@@ -83,7 +127,7 @@ module FiberStream
|
|
|
83
127
|
def via(flow)
|
|
84
128
|
raise TypeError, "expected FiberStream::Flow" unless flow.is_a?(Flow)
|
|
85
129
|
|
|
86
|
-
self.class.
|
|
130
|
+
self.class.build(@source_factory, @flows + [flow])
|
|
87
131
|
end
|
|
88
132
|
|
|
89
133
|
# Returns a new source definition that emits this source, then `source`.
|
|
@@ -95,10 +139,7 @@ module FiberStream
|
|
|
95
139
|
def concat(source)
|
|
96
140
|
raise TypeError, "expected FiberStream::Source" unless source.is_a?(Source)
|
|
97
141
|
|
|
98
|
-
self.class.
|
|
99
|
-
:new,
|
|
100
|
-
-> { Pull.concat(materializer, source.__send__(:materializer)) }
|
|
101
|
-
)
|
|
142
|
+
self.class.build(-> { Pull.concat(to_pull_materializer, source.to_pull_materializer) })
|
|
102
143
|
end
|
|
103
144
|
|
|
104
145
|
# Returns a new source definition that emits pairs from this source and
|
|
@@ -111,10 +152,7 @@ module FiberStream
|
|
|
111
152
|
def zip(source)
|
|
112
153
|
raise TypeError, "expected FiberStream::Source" unless source.is_a?(Source)
|
|
113
154
|
|
|
114
|
-
self.class.
|
|
115
|
-
:new,
|
|
116
|
-
-> { Pull.zip(materializer, source.__send__(:materializer)) }
|
|
117
|
-
)
|
|
155
|
+
self.class.build(-> { Pull.zip(to_pull_materializer, source.to_pull_materializer) })
|
|
118
156
|
end
|
|
119
157
|
|
|
120
158
|
# Returns a new source definition that emits values from this source and
|
|
@@ -128,10 +166,7 @@ module FiberStream
|
|
|
128
166
|
def merge(source)
|
|
129
167
|
raise TypeError, "expected FiberStream::Source" unless source.is_a?(Source)
|
|
130
168
|
|
|
131
|
-
self.class.
|
|
132
|
-
:new,
|
|
133
|
-
-> { Pull.merge(materializer, source.__send__(:materializer)) }
|
|
134
|
-
)
|
|
169
|
+
self.class.build(-> { Pull.merge(to_pull_materializer, source.to_pull_materializer) })
|
|
135
170
|
end
|
|
136
171
|
|
|
137
172
|
# Returns a new source definition that maps each element with `block`.
|
|
@@ -153,6 +188,18 @@ module FiberStream
|
|
|
153
188
|
via(Flow.parallel_map(concurrency: concurrency, &block))
|
|
154
189
|
end
|
|
155
190
|
|
|
191
|
+
# Returns a new source definition that maps elements concurrently and emits
|
|
192
|
+
# mapped values in completion order.
|
|
193
|
+
#
|
|
194
|
+
# This is a convenience wrapper around
|
|
195
|
+
# `via(FiberStream::Flow.parallel_unordered_map(concurrency:) { ... })`.
|
|
196
|
+
# The operation preserves the same scheduler requirement, validation,
|
|
197
|
+
# bounded upstream run-ahead, and cancellation behavior while making no
|
|
198
|
+
# input-order guarantee.
|
|
199
|
+
def parallel_unordered_map(concurrency:, &block)
|
|
200
|
+
via(Flow.parallel_unordered_map(concurrency: concurrency, &block))
|
|
201
|
+
end
|
|
202
|
+
|
|
156
203
|
# Returns a new source definition that maps elements in Ractor workers.
|
|
157
204
|
#
|
|
158
205
|
# This is a convenience wrapper around
|
|
@@ -204,6 +251,15 @@ module FiberStream
|
|
|
204
251
|
via(Flow.grouped(count))
|
|
205
252
|
end
|
|
206
253
|
|
|
254
|
+
# Returns a new source definition that emits running accumulators.
|
|
255
|
+
#
|
|
256
|
+
# This is a convenience wrapper around
|
|
257
|
+
# `via(FiberStream::Flow.scan(initial) { ... })` and preserves the same
|
|
258
|
+
# reducer order, lazy construction, and pull-driven backpressure behavior.
|
|
259
|
+
def scan(initial, &block)
|
|
260
|
+
via(Flow.scan(initial, &block))
|
|
261
|
+
end
|
|
262
|
+
|
|
207
263
|
# Returns a new source definition that emits leading elements while `block`
|
|
208
264
|
# is truthy.
|
|
209
265
|
#
|
|
@@ -270,7 +326,7 @@ module FiberStream
|
|
|
270
326
|
def to(sink)
|
|
271
327
|
raise TypeError, "expected FiberStream::Sink" unless sink.is_a?(Sink)
|
|
272
328
|
|
|
273
|
-
Pipeline.
|
|
329
|
+
Pipeline.build(self, sink)
|
|
274
330
|
end
|
|
275
331
|
|
|
276
332
|
# Materializes and runs this source with `sink`.
|
|
@@ -286,7 +342,7 @@ module FiberStream
|
|
|
286
342
|
begin
|
|
287
343
|
stream = materialize
|
|
288
344
|
|
|
289
|
-
sink.
|
|
345
|
+
sink.run_stream(stream)
|
|
290
346
|
rescue StandardError => error
|
|
291
347
|
primary_error = error
|
|
292
348
|
raise
|
|
@@ -301,6 +357,10 @@ module FiberStream
|
|
|
301
357
|
|
|
302
358
|
private_class_method :new
|
|
303
359
|
|
|
360
|
+
def to_pull_materializer # :nodoc:
|
|
361
|
+
method(:materialize)
|
|
362
|
+
end
|
|
363
|
+
|
|
304
364
|
def self.normalize_ractor_merge_port_pairs(ports)
|
|
305
365
|
raise TypeError, "ports must respond to each" unless ports.respond_to?(:each)
|
|
306
366
|
|
|
@@ -341,17 +401,13 @@ module FiberStream
|
|
|
341
401
|
|
|
342
402
|
private
|
|
343
403
|
|
|
344
|
-
def materializer
|
|
345
|
-
-> { materialize }
|
|
346
|
-
end
|
|
347
|
-
|
|
348
404
|
def materialize
|
|
349
405
|
stream = nil
|
|
350
406
|
|
|
351
407
|
begin
|
|
352
408
|
stream = @source_factory.call
|
|
353
409
|
@flows.each do |flow|
|
|
354
|
-
stream = flow.
|
|
410
|
+
stream = flow.attach_to(stream)
|
|
355
411
|
end
|
|
356
412
|
stream
|
|
357
413
|
rescue StandardError
|
data/lib/fiber_stream/version.rb
CHANGED
data/lib/fiber_stream.rb
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
require_relative "fiber_stream/pull"
|
|
4
4
|
require_relative "fiber_stream/version"
|
|
5
5
|
require_relative "fiber_stream/errors"
|
|
6
|
+
require_relative "fiber_stream/internal/ractor_transfer_policy"
|
|
6
7
|
require_relative "fiber_stream/ractor_port"
|
|
8
|
+
require_relative "fiber_stream/ractor_producer"
|
|
7
9
|
require_relative "fiber_stream/flow"
|
|
8
10
|
require_relative "fiber_stream/sink"
|
|
9
11
|
require_relative "fiber_stream/running_pipeline"
|
data/sig/fiber_stream.rbs
CHANGED
|
@@ -2,7 +2,7 @@ module FiberStream
|
|
|
2
2
|
type ractor_transfer_policy = :copy | :move
|
|
3
3
|
type ractor_port_pair = { port: untyped, ack_port: untyped }
|
|
4
4
|
type ractor_map_error_kind = :input_transfer | :output_transfer | :worker | :worker_termination | :isolation
|
|
5
|
-
type ractor_port_source_error_kind = :invalid_message | :producer_failure | :receive | :ack_transfer | :cancel_transfer
|
|
5
|
+
type ractor_port_source_error_kind = :invalid_message | :producer_failure | :receive | :ack_transfer | :cancel_transfer | :producer_setup
|
|
6
6
|
type ractor_port_cancel_reason = :closed
|
|
7
7
|
|
|
8
8
|
class SchedulerRequiredError < RuntimeError
|
|
@@ -48,22 +48,37 @@ module FiberStream
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
class RactorProducer
|
|
52
|
+
def emit: [Elem] (Elem value, ?transfer: ractor_transfer_policy?) -> bool
|
|
53
|
+
def complete: () -> bool
|
|
54
|
+
def fail: (?untyped error, ?cause_class_name: String?, ?cause_message: String?) -> bool
|
|
55
|
+
def cancelled?: () -> bool
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class RactorProducerGroup
|
|
59
|
+
def producer: (*untyped args, ?transfer: ractor_transfer_policy?) { (RactorProducer producer, *untyped args) -> void } -> self
|
|
60
|
+
end
|
|
61
|
+
|
|
51
62
|
class Source[Elem]
|
|
52
63
|
def self.each: [Elem] (Enumerable[Elem] enumerable) -> Source[Elem]
|
|
53
64
|
def self.io: (untyped io, ?chunk_size: Integer, ?close: bool) -> Source[String]
|
|
54
65
|
def self.ractor_port: [Elem] (untyped port, ack_port: untyped, ?ack_transfer: ractor_transfer_policy, ?cancel: bool) -> Source[Elem]
|
|
55
66
|
def self.ractor_merge_ports: [Elem] (Enumerable[ractor_port_pair] ports, ?ack_transfer: ractor_transfer_policy, ?cancel: bool) -> Source[Elem]
|
|
67
|
+
def self.ractor_producer: [Elem] (*untyped args, ?transfer: ractor_transfer_policy, ?ack_transfer: ractor_transfer_policy) { (RactorProducer producer, *untyped args) -> void } -> Source[Elem]
|
|
68
|
+
def self.ractor_merge_producers: [Elem] (?transfer: ractor_transfer_policy, ?ack_transfer: ractor_transfer_policy) { (RactorProducerGroup group) -> void } -> Source[Elem]
|
|
56
69
|
def via: [Out] (Flow[Elem, Out] flow) -> Source[Out]
|
|
57
70
|
def concat: [Other] (Source[Other] source) -> Source[Elem | Other]
|
|
58
71
|
def zip: [Other] (Source[Other] source) -> Source[[Elem, Other]]
|
|
59
72
|
def merge: [Other] (Source[Other] source) -> Source[Elem | Other]
|
|
60
73
|
def map: [Out] () { (Elem) -> Out } -> Source[Out]
|
|
61
74
|
def parallel_map: [Out] (concurrency: Integer) { (Elem) -> Out } -> Source[Out]
|
|
75
|
+
def parallel_unordered_map: [Out] (concurrency: Integer) { (Elem) -> Out } -> Source[Out]
|
|
62
76
|
def ractor_map: [Out] (workers: Integer, ?input_transfer: ractor_transfer_policy, ?output_transfer: ractor_transfer_policy) { (Elem) -> Out } -> Source[Out]
|
|
63
77
|
def select: () { (Elem) -> boolish } -> Source[Elem]
|
|
64
78
|
def take: (Integer count) -> Source[Elem]
|
|
65
79
|
def drop: (Integer count) -> Source[Elem]
|
|
66
80
|
def grouped: (Integer count) -> Source[Array[Elem]]
|
|
81
|
+
def scan: [Acc] (Acc initial) { (Acc, Elem) -> Acc } -> Source[Acc]
|
|
67
82
|
def take_while: () { (Elem) -> boolish } -> Source[Elem]
|
|
68
83
|
def drop_while: () { (Elem) -> boolish } -> Source[Elem]
|
|
69
84
|
def async: () -> Source[Elem]
|
|
@@ -77,11 +92,13 @@ module FiberStream
|
|
|
77
92
|
class Flow[In, Out]
|
|
78
93
|
def self.map: [In, Out] () { (In) -> Out } -> Flow[In, Out]
|
|
79
94
|
def self.parallel_map: [In, Out] (concurrency: Integer) { (In) -> Out } -> Flow[In, Out]
|
|
95
|
+
def self.parallel_unordered_map: [In, Out] (concurrency: Integer) { (In) -> Out } -> Flow[In, Out]
|
|
80
96
|
def self.ractor_map: [In, Out] (workers: Integer, ?input_transfer: ractor_transfer_policy, ?output_transfer: ractor_transfer_policy) { (In) -> Out } -> Flow[In, Out]
|
|
81
97
|
def self.select: [Elem] () { (Elem) -> boolish } -> Flow[Elem, Elem]
|
|
82
98
|
def self.take: [Elem] (Integer count) -> Flow[Elem, Elem]
|
|
83
99
|
def self.drop: [Elem] (Integer count) -> Flow[Elem, Elem]
|
|
84
100
|
def self.grouped: [Elem] (Integer count) -> Flow[Elem, Array[Elem]]
|
|
101
|
+
def self.scan: [Elem, Acc] (Acc initial) { (Acc, Elem) -> Acc } -> Flow[Elem, Acc]
|
|
85
102
|
def self.take_while: [Elem] () { (Elem) -> boolish } -> Flow[Elem, Elem]
|
|
86
103
|
def self.drop_while: [Elem] () { (Elem) -> boolish } -> Flow[Elem, Elem]
|
|
87
104
|
def self.async: [Elem] () -> Flow[Elem, Elem]
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fiber_stream
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dai Akatsuka
|
|
@@ -119,9 +119,11 @@ files:
|
|
|
119
119
|
- examples/ractor_map_hashing.rb
|
|
120
120
|
- examples/ractor_merge_ports_and_map.rb
|
|
121
121
|
- examples/ractor_port_source.rb
|
|
122
|
+
- examples/ractor_producer_sources.rb
|
|
122
123
|
- lib/fiber_stream.rb
|
|
123
124
|
- lib/fiber_stream/errors.rb
|
|
124
125
|
- lib/fiber_stream/flow.rb
|
|
126
|
+
- lib/fiber_stream/internal/ractor_transfer_policy.rb
|
|
125
127
|
- lib/fiber_stream/pipeline.rb
|
|
126
128
|
- lib/fiber_stream/pull.rb
|
|
127
129
|
- lib/fiber_stream/pull/async_boundary.rb
|
|
@@ -136,15 +138,19 @@ files:
|
|
|
136
138
|
- lib/fiber_stream/pull/map.rb
|
|
137
139
|
- lib/fiber_stream/pull/merge.rb
|
|
138
140
|
- lib/fiber_stream/pull/parallel_map_boundary.rb
|
|
141
|
+
- lib/fiber_stream/pull/parallel_unordered_map_boundary.rb
|
|
139
142
|
- lib/fiber_stream/pull/ractor_map_boundary.rb
|
|
140
143
|
- lib/fiber_stream/pull/ractor_merge_ports_source.rb
|
|
141
144
|
- lib/fiber_stream/pull/ractor_port_source.rb
|
|
145
|
+
- lib/fiber_stream/pull/ractor_producer_source.rb
|
|
146
|
+
- lib/fiber_stream/pull/scan.rb
|
|
142
147
|
- lib/fiber_stream/pull/select.rb
|
|
143
148
|
- lib/fiber_stream/pull/split.rb
|
|
144
149
|
- lib/fiber_stream/pull/take.rb
|
|
145
150
|
- lib/fiber_stream/pull/take_while.rb
|
|
146
151
|
- lib/fiber_stream/pull/zip.rb
|
|
147
152
|
- lib/fiber_stream/ractor_port.rb
|
|
153
|
+
- lib/fiber_stream/ractor_producer.rb
|
|
148
154
|
- lib/fiber_stream/running_pipeline.rb
|
|
149
155
|
- lib/fiber_stream/sink.rb
|
|
150
156
|
- lib/fiber_stream/source.rb
|
|
@@ -156,7 +162,7 @@ licenses:
|
|
|
156
162
|
metadata:
|
|
157
163
|
allowed_push_host: https://rubygems.org
|
|
158
164
|
homepage_uri: https://github.com/dakatsuka/fiber_stream
|
|
159
|
-
source_code_uri: https://github.com/dakatsuka/fiber_stream/tree/v0.
|
|
165
|
+
source_code_uri: https://github.com/dakatsuka/fiber_stream/tree/v0.4.0
|
|
160
166
|
changelog_uri: https://github.com/dakatsuka/fiber_stream/blob/main/CHANGELOG.md
|
|
161
167
|
rubygems_mfa_required: 'true'
|
|
162
168
|
rdoc_options: []
|
|
@@ -173,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
173
179
|
- !ruby/object:Gem::Version
|
|
174
180
|
version: '0'
|
|
175
181
|
requirements: []
|
|
176
|
-
rubygems_version: 4.0.
|
|
182
|
+
rubygems_version: 4.0.10
|
|
177
183
|
specification_version: 4
|
|
178
184
|
summary: Asynchronous, non-blocking stream processing with backpressure.
|
|
179
185
|
test_files: []
|