【问题标题】:Running an EventMachine Worker on Heroku + Sinatra + Twitter Streaming API?在 Heroku + Sinatra + Twitter 流 API 上运行 EventMachine Worker?
【发布时间】:2011-08-29 09:32:16
【问题描述】:

我正试图了解使用 Sinatra 在 Heroku 上运行 eventmachine 所涉及的异步模式。简而言之,我想要实现的是:使用 em-http 创建对 twitter 流 api 的 http 请求,在 stream 回调上,解析和推送使用 websockets 向客户发送推文。到目前为止,一切都很好。当同一个应用程序也需要提供网页服务时,就会出现问题。在我的 config.ru 中,除了其他 Bundler 的东西,我还有,

require 'app'
run TwitterApp

然后在我的应用文件中,EM 块:

EM.run{
 class TwitterApp < Sinatra::Base {
       get '/' do
        haml :index
       end
 }
 http = EventMachine::HttpRequest.new(url, options).get :head=>{'Authorization' => [USERNAME, PASSWORD]}
 http.stream do |chunk|
    #parse tweet, push using websockets
  end
}

现在,似乎正在发生的事情是 run TwitterApp 永远不会到达,因为 EventMachine 使用 Reactor 模式并且永远不会返回。

或者,如果我尝试做一个

App.run!

在 EM.run 块中,一切都在本地运行良好并使用 ruby app.rb 运行,但使用 rackup 似乎运行服务器两次(一次使用瘦另一个使用 WEBrick),在 Heroku 上它崩溃了

Error R11 (Bad bind) -> Process bound to port other than $PORT
Stopping process with SIGKILL

我在这里错过了一些非常琐碎的事情吗?

非常感谢!

【问题讨论】:

    标签: heroku sinatra eventmachine


    【解决方案1】:

    为此,您可以只运行 async_sinatra -- https://github.com/raggi/async_sinatra -- 并使用它的异步处理程序而不是滚动您自己的处理程序。

    【讨论】:

      【解决方案2】:

      我在它自己的线程中运行反应器,这样它就不会阻塞主进程:

        if not EM.reactor_running?
          Thread.new {
            EM.run {
              logger.info "Starting EventMachine Reactor"
              EM.error_handler{ |e|
                logger.error "Error raised during event loop: #{e.message}"
                logger.error e.backtrace unless e.backtrace.nil?
              }
            }
          }
        else
          logger.info "Reactor already started"
        end
      

      然后我通过

       EM.next_tick { do_background_stuff }
      

      我仍在等待发现您需要有一个 Worker Dyno 才能使用此模式。

      【讨论】:

      • > 我还在等着发现你需要一个 Worker Dyno 才能使用这个模式。你发现了吗?
      【解决方案3】:

      我对 Eventmachine 不太熟悉,但据我了解,Heroku 尚不支持 Websockets。像 travis-ci 这样的项目通过使用像 Pusher 这样的服务来服务他们的 Websockets 来解决这个问题。

      Heroku 上的 R11(错误绑定)错误意味着您必须确保您的 Web Worker 绑定到它从 Heroku 获得的端口 (ENV["PORT"])。我猜这可以确保支持 HTTP 路由。

      我希望这在某种程度上有所帮助。

      【讨论】:

        【解决方案4】:

        您可以将您的应用分成多个服务器实例。应用程序 1 提供网页服务,应用程序 2 运行事件机器服务器(两者都连接到同一个数据库)。您可以使用Pusher 将它们与 Web 套接字粘合在一起。

        您能否粘贴完整 Sinatra 应用程序的要点?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-31
          • 1970-01-01
          • 1970-01-01
          • 2016-11-25
          相关资源
          最近更新 更多