Asynchronously Iterating Over The Response of a Request Using Thin and Sinatra

Asynchronously iterating over the response of a request using Thin and Sinatra

So in the end, I found out that the example did indeed work and I could eventually get Sinatra to stream each-able results concurrently, primarily using the EM.defer idea in Pusher and Async page. curl and Apache benchmarking confirmed that this was working.

The reason why it didn't work in the browser is because browsers limit the number of connections to the same URL. I was aware of there being a limit to concurrent connections to a single domain (also a low number), but not that (seemingly) all connections to a single URI are serialized:

http://maillist.caucho.com/pipermail/resin-interest/2009-August/003998.html

I don't know if this is configurable, I only see domain-wide configuration in Firefox, but that was the issue.

stream multiple body using async sinatra

require 'rubygems'
require 'sinatra/async'
require 'thin'
require 'json'

class Test < Sinatra::Base
register Sinatra::Async

class JSONStream
include EventMachine::Deferrable

def stream(object)
@block.call object.to_json + "\n"
end

def each(&block)
@block = block
end
end

aget '/process' do
puts 'ok'
out = JSONStream.new
body out
EM.next_tick do
c = 0
timer = EM.add_periodic_timer(0.3) do
c += 1
out.stream :data => ["this is part #{c}"]
if c == 100
timer.cancel
out.succeed
end
end
end
end

run!
end

See also: http://confreaks.net/videos/564-scotlandruby2011-real-time-rack

Running Sinatra server and subprocess asynchronously

Here the main thread is the Sinatra app and the additional thread loads the data, which is more usual to me.

class Aircraft
@aircrafts = {}

def self.all
@aircrafts
end
end

Thread.new do
no = 1
while true
Aircraft.all[no] = 'Boing'
no += 1
sleep(3)
end
end

get '/aircrafts' do
Aircraft.all.to_json
end

sinatra HEAD method

That is a perfectly valid Sinatra head route. The problem is with your curl statement.

curl -X HEAD 'http://localhost:4567/'

-X HEAD is not what you want; it will not print headers and will expect some specification of expected bytes transmission stated in Content-Length.

Instead you want the following.

curl -I http://localhost:4567/

async_sinatra requests crash silently with em-http. How do I fix this?

If your web server (Eg. thin) is based on EventMachine, then the EventMachine.stop line will actually stop the webserver as well as the EventMachine instance created by EventMachine.run.

I can't find a way to stop nested EventMachines like this. My advice - use Weary or another non-blocking HTTP request library.

Ruby Http gem (http client) inside Sinatra POST

Changes to

post "/weather" do
puts HTTP.get('https://www.metaweather.com/api/location/search/?query=milwaukee') # prints correct result
HTTP.get('https://www.metaweather.com/api/location/search/?query=milwaukee').to_s
end

The HTTP.get method returns a HTTP::Response object rather than a String object.


From the source code only specific types of object can be returned.

 res = [res] if Integer === res or String === res
if Array === res and Integer === res.first
res = res.dup
status(res.shift)
body(res.pop)
headers(*res)
elsif res.respond_to? :each
body res
end
nil # avoid double setting the same response tuple twice


Related Topics



Leave a reply



Submit