145 lines
2.2 KiB
Ruby
145 lines
2.2 KiB
Ruby
require 'json'
|
|
|
|
class Counter
|
|
def initialize
|
|
@count = 0
|
|
end
|
|
|
|
def increment
|
|
@count += 1
|
|
end
|
|
|
|
def clear
|
|
@count = 0
|
|
end
|
|
|
|
def count
|
|
@count
|
|
end
|
|
end
|
|
|
|
class Stream
|
|
def initialize(out, buf_size = 10, counter = nil, root = self)
|
|
counter = Counter.new if counter.nil?
|
|
@buf_size = buf_size
|
|
@out = out
|
|
@counter = counter
|
|
@root = root
|
|
@data = {}
|
|
@substreams = {}
|
|
@first = true
|
|
end
|
|
|
|
def start
|
|
'['
|
|
end
|
|
|
|
def start!
|
|
@out.write(start)
|
|
end
|
|
|
|
def flush
|
|
if @root == self
|
|
r = to_json
|
|
clear
|
|
@out.write(r)
|
|
@out.flush
|
|
return r
|
|
end
|
|
end
|
|
|
|
def stop
|
|
']'
|
|
end
|
|
|
|
def stop!
|
|
flush
|
|
@out.write(stop)
|
|
end
|
|
|
|
def clear
|
|
@counter.clear
|
|
@data = {}
|
|
@substreams.values.each do | substream |
|
|
substream.clear
|
|
end
|
|
end
|
|
|
|
def output(stream_name, obj)
|
|
if not @data.keys.include? stream_name
|
|
@data[stream_name] = []
|
|
end
|
|
@data[stream_name].push(obj)
|
|
@counter.increment
|
|
if @counter.count >= @buf_size
|
|
@root.flush
|
|
end
|
|
end
|
|
|
|
def new_stream(name)
|
|
s = Stream.new(@out, @buf_size, @counter, @root)
|
|
@substreams[name] = s
|
|
s
|
|
end
|
|
|
|
def empty?
|
|
empty = @data == {}
|
|
@substreams.values.each do |substream|
|
|
empty = empty and substream.empty?
|
|
end
|
|
empty
|
|
end
|
|
|
|
def add_comma_if_not_first(s)
|
|
if @first
|
|
@first = false
|
|
else
|
|
s.push(',')
|
|
end
|
|
end
|
|
|
|
def to_json
|
|
s = []
|
|
if not @data.empty?
|
|
add_comma_if_not_first(s)
|
|
s.push(@data.to_json)
|
|
end
|
|
@substreams.each do |key, stream|
|
|
if not stream.empty?
|
|
add_comma_if_not_first(s)
|
|
s.push("{#{key}:")
|
|
s.push(stream.start)
|
|
s.push(stream.to_json)
|
|
s.push(stream.stop)
|
|
s.push('}')
|
|
end
|
|
end
|
|
s.join ''
|
|
end
|
|
end
|
|
|
|
|
|
def main
|
|
s = Stream.new $stdout, 4
|
|
s.start!
|
|
7.times do |i|
|
|
proc = {:pid => i + 1, :name => "init"}
|
|
s.output(:things, proc)
|
|
end
|
|
q = s.new_stream 'q'
|
|
q.output(:test, 'potato')
|
|
|
|
10.times do |i|
|
|
proc = {:pid => i + 1, :name => "init"}
|
|
s.output(:processes, proc)
|
|
end
|
|
|
|
q.output(:test, "salad")
|
|
q.output(:test, "rocks")
|
|
|
|
s.flush
|
|
s.stop!
|
|
end
|
|
|
|
|
|
main |