Rails プロジェクトに Sinatra クラスがあります。eventmachine と async_sinatra を使用して、外部サイトへの非同期呼び出しを行います。セッション オブジェクト (理想的には、Rails が使用しているものと同じもの) に書き込みたいのですが、今のところ次のことしかできません。
- Rails とは別のセッション オブジェクトに書き込みます (デフォルトでは、Sinatra はそのセッションに Rails とは異なる名前を付けます)。
- 同期呼び出しのみの同じセッションへの書き込み
非同期呼び出しを行うと、async_sinatra コードで記述されたセッションがクライアント マシンにプッシュされません。次の 2 つのいずれかが起こっていると思われます。
ヘッダーはすでにクライアントに送信されており、セッションを格納しているローカル変数 (Sinatra 内) はアクションの最後にフラッシュされます。クライアントは、このデータを Cookie に保存するというサーバーからの要求を認識しません。
ヘッダーはクライアントに送信されていますが、Rails はすぐに別のヘッダーを送信し、Rails がその
session
変数に格納したものを Cookie に書き込み、Sinatra が書き込んだものを上書きするようにクライアントに指示します。
いずれにせよ、Sinatra と Rails の両方で単純なセッション機能を取得したいと考えています。私が間違っていることの説明もいいでしょう:)
コードの完全な作業コピーはgithubにありますが、問題は特に次のコードにあると思います。
class ExternalCall < Sinatra::Base
use ActionDispatch::Session::CookieStore
register Sinatra::Async
get '/sinatra/local' do
session[:demo] = "sinatra can write to Rails' session"
end
aget '/sinatra/goog' do
session[:async_call]="async sinatra calls cannot write to Rails' session"
make_async_req :get, "http://www.google.com/" do |http_callback|
if http_callback
session[:em_callback] = "this also isn't saving for me"
else
headers 'Status' => '422'
end
async_schedule { redirect '/' }
end
end
helpers do
def make_async_req(method, host, opts={}, &block)
opts[:head] = { 'Accept' => 'text/html', 'Connection' => 'keep-alive' }
http = EM::HttpRequest.new(host)
http = http.send(method, {:head => opts[:head], :body => {}, :query => {}})
http.callback &block
end
end
end
編集 7/15 :
Async-Rack を含めるように Github のコードを変更しました。Rails と共有されていない場合、async-sinatra はセッションに書き込むことができます。master
とのsegmented_sessions
ブランチを比較して、動作の違いを確認します。(またはmaster
ブランチで、にuse ActionDispatch::Session::CookieStore
変更enable :sessions
)