2

Sinatra を使用して Heroku で eventmachine を実行する際の非同期パターンについて理解しようとしています。簡単に言えば、私が達成しようとしているのはこれです: em-httpを使用して Twitter ストリーミング API への http 要求を作成し、ストリームコールバックで、websockets を使用してツイートを解析し、クライアントにプッシュします。ここまでは順調ですね。問題は、同じアプリケーションが Web ページも提供する必要がある場合に発生します。私の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
}

現在、何が起こっているように見えるかというと、EventMachine が Reactor パターンを使用して返されないため、 run TwitterAppに到達することはありません。

代わりに、私がやろうとすると

App.run!

EM.run ブロック内では、すべてがローカルで正常に実行され、ruby​​ app.rb使用して実行されますが、ラックアップを使用すると、サーバーが 2 回 (1 回は Thin で、もう 1 回は WEBrick で) 実行されるようで、Heroku では次のようにクラッシュします。

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

ここで非常に些細なことを見逃していますか?

どうもありがとう!

4

4 に答える 4

3

このためには、async_sinatra ( https://github.com/raggi/async_sinatra )を実行するだけで、独自のハンドラーをロールするのではなく、その非同期ハンドラーを使用できます。

于 2011-09-07T20:49:22.447 に答える
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 が必要であることが判明するのを待っています。

于 2011-08-11T23:59:16.310 に答える
1

私は Eventmachine にはあまり詳しくありませんが、私が理解している限り、Heroku では Websocket はまだサポートされていません。travis-ci のようなプロジェクトは、Pusher のようなサービスを使用して Websocket を提供することで、この問題を回避しています。

Heroku の R11 (bad bind) エラーは、Web Worker が Heroku から取得したポートにバインドされていることを確認する必要があることを意味します ( ENV["PORT"])。これにより、HTTP ルーティングが確実にサポートされるようになります。

これが何らかの形で役立つことを願っています。

于 2012-01-22T08:03:34.957 に答える
0

アプリを複数のサーバー インスタンスに分割できます。アプリ 1 は Web ページを提供し、アプリ 2 はイベント マシン サーバーを実行します (両方とも同じデータベースに接続されています)。Pusherを使用して、Web ソケットと一緒に接着することができます。

Sinatra アプリ全体の要点を貼り付けていただけますか?

于 2011-05-30T02:29:59.113 に答える