# reading a file
# as we read and encounter <esi:include src="/foo"/>
# spawn a thread and simulate requesting, but continue parsing the file looking for more on the main thread
# tweak the sleep calls to get different behavior...
require 'thread'
# define a sample buffer here:
input_stream = %Q(
hello there world
<esi:include src='/foo/'/>
some more bytes here
<esi:include src='/bar/'/>
and some more here
)
# lets read line by line
count = 0
output = []
back_buffer = []
lock = Mutex.new
in_request = false
requesting = []
last_out = 0
input_stream.split("\n").each do|line|
if line.match(/<esi:/)
lock.synchronize do
in_request = true
back_buffer[count] = nil # reserve a location in back_buffer
end
requesting << Thread.new(count) do|id|
sleep 0.4 # some busy work
lock.synchronize do
back_buffer[id] = "#{id}: sample"
in_request = false
end
end
else
sleep 0.1
lock.synchronize do
if in_request
puts "buffering lines..."
back_buffer[count] = "#{count}: #{line}"
else
# roll up requests
puts "roll up requests..."
i = 0
until i == count
o = back_buffer.shift
output << o unless o.nil?
i += 1
end
output << "#{count}: #{line}"
last_out = count # mark the last buffer in back_buffer to be sent
end
end
end
count += 1
end
requesting.each do|t|
t.join
end
# roll up requests
while !back_buffer.empty?
o = back_buffer.shift
output << o unless o.nil?
end
puts back_buffer.inspect
puts output.join("\n")
One obvious issue with this implementation is the number of threads per request is bounded by the response document.
Update: I've checked the above into svn, with a few updates

0 comments:
Post a Comment