I'm building a Sinatra app that uses TweetStream (which listens for Tweets using EventMachine). I would also like the app to serve pages like a normal Sinatra app but it seems like Sinatra can't "listen" for page requests when it's "listening" for Tweets.
Is this something I can fix by using a different server or structuring my app in a different way? I've tried using WebBrick and Thin.
Here is basically what I'm doing:
class App < Sinatra::Base
# listening for tweets
@client = TweetStream::Client.new
@client.track(terms) do |status|
# do some stuff when I detect terms
end
get '/' do
"Here's some page content!"
end
end
You can mount Sinatra apps within eventmachine (providing you you a awebserver that supports EM i.e., Thin). You should then have full access to the EM reactor loop from your Sinatra app, as well as allowing any other EM plugins to run too.
The Sinatra recipes have a good example:
http://recipes.sinatrarb.com/p/embed/event-machine
here is a very stripped down version of the code:
require 'eventmachine'
require 'sinatra/base'
require 'thin'
def run(opts)
EM.run do
server = opts[:server] || 'thin'
host = opts[:host] || '0.0.0.0'
port = opts[:port] || '8181'
web_app = opts[:app]
dispatch = Rack::Builder.app do
map '/' do
run web_app
end
end
unless ['thin', 'hatetepe', 'goliath'].include? server
raise "Need an EM webserver, but #{server} isn't"
end
Rack::Server.start({
app: dispatch,
server: server,
Host: host,
Port: port
})
end
end
class HelloApp < Sinatra::Base
configure do
set :threaded, false
end
get '/hello' do
'Hello World'
end
get '/delayed-hello' do
EM.defer do
sleep 5
end
'I\'m doing work in the background, but I am still free to take requests'
end
end
run app: HelloApp.new