You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I found that Concurrent::Channel is great for representing stream data.
Initial problem was, that I needed to stream data in JRuby with Sinatra (so i stuck with Puma and was not able to use embedded sinatra stream module, which require Rainbows).
Concurrent::Channel fits almost ideally, but it needs to have some protection from unstarted stream && some callbacks in the end. Idk if it is only my implementation related, it is required in general. Anyway, I feel that it is a good usage of a lib. Before making a PR wanted to ask you first if this is worth it, or it is my very specific use case related only from your perspective.
Sample code with usage examples:
require"concurrent-edge"moduleConcurrentclassStreamingChannel < Channel# Array, where each element must respond_to :calldefafter_each_callbacks@after_each_callbacks ||= []end# After first data out we mark the stream as started.# This allows to determine in other threads which channels should be killed as inactivedefeachraiseArgumentError.new('no block given')unlessblock_given?item,more=do_nextyield(item)unlessitem == Concurrent::NULLreturnunlessmorestarted!superensureafter_each_callbacks.each{ |cb| cb.call(self)}end# if we processed at least something, we assume, that the streaming process# initiated correctly, otherwisedefstarted!@stream_started=trueenddefstarted?
!!@stream_startedendendend# This illustrates how we can use a callbacks with the streaming channeldefcallbacks_usage_demoputs'started callbacks usage demo'chan=Concurrent::StreamingChannel.new(capacity: 100)chan.after_each_callbacks << ->(channel){puts"Hi from callback with #{channel}"}ticker=Concurrent::Channel.tick(0.2)boom=Concurrent::Channel.after(1.02)Thread.new{ticker.inject(0){ |a,_e| chan << ".";a > 100 ? break : a + 1};chan.close}Thread.new{boom.take;puts"boom";chan.close}chan.each{ |m| printm}puts"ended"endcallbacks_usage_demodefstuck_streams_detection_demo# This illustrates how we can determine and manage stuck streamsputs'started stack streams detection demo'chan=Concurrent::StreamingChannel.new(capacity: 100)chan.after_each_callbacks << ->(channel){puts"Hi from callback with #{channel}"}Thread.newdo
~Concurrent::Channel.timer(1)puts'some timeout reached, need to check if the channel started'chan.closeunlesschan.started?endputs"Is channel closed? #{chan.closed?}"chan.each{ |m| printm}puts"Is channel closed? #{chan.closed?}"puts"ended"endstuck_streams_detection_demo
This piece of code produce:
started callbacks usage demo
.....boom
Hi from callback with #<Concurrent::StreamingChannel:0x00007fd28d919508>
ended
started stack streams detection demo
Is channel closed? false
some timeout reached, need to check if the channel started
Hi from callback with #<Concurrent::StreamingChannel:0x00007fd28d8abb20>
Is channel closed? true
ended
The text was updated successfully, but these errors were encountered:
I found that
Concurrent::Channel
is great for representing stream data.Initial problem was, that I needed to stream data in JRuby with Sinatra (so i stuck with Puma and was not able to use embedded sinatra stream module, which require Rainbows).
Concurrent::Channel
fits almost ideally, but it needs to have some protection from unstarted stream && some callbacks in the end. Idk if it is only my implementation related, it is required in general. Anyway, I feel that it is a good usage of a lib. Before making a PR wanted to ask you first if this is worth it, or it is my very specific use case related only from your perspective.Sample code with usage examples:
This piece of code produce:
The text was updated successfully, but these errors were encountered: