EventMachine приостановить ожидание ответа - PullRequest
2 голосов
/ 26 марта 2011

Хорошо, у меня есть код, который использует Cramp \ Tramp => EventMachine под капотом. Код:

class RetrieveController < ApplicationController
  on_start :retrieve_messages

#nonimportant stuff


def receive_messages
  #other stuff
  @current_user = false  
  User.where(User[:id].eq("request.env['rack.session']['user_id']")).all method(:retrieve_current_user)
  if wait_for_current_user
    EM.add_periodic_timer(1) {wait_for_current_user}
  else
    render @current_user
    finish
  end
 end

 def wait_for_current_user
   if @current_user
     render "current_user is set"
     true
   else
     render "waiting for current_user"
     false
   end
 end

 def retrieve_current_user(users)
   users.each do |user|
     @current_user = user.name
   end
 end

end

Мне нужны результаты запроса для продолжения выполнения в действии контроллера, но похоже, что выполнение завершено до того, как я получу данные Визуализированный текст:

ожидание current_user ложь

мой гемфайл:

source 'http://rubygems.org'

gem 'cramp', '~> 0.12'
gem 'tramp', '~> 0.2'

gem 'activesupport', '3.0.4'
gem 'rack', '~> 1.2.1'
gem 'eventmachine', '~> 0.12.10'

gem 'usher', '~> 0.8.3'
gem 'thin', '~> 1.2.7'
gem "bcrypt-ruby", :require => "bcrypt"

1 Ответ

1 голос
/ 13 марта 2012

Я не использовал Cramp / Tramp, поэтому извините, если мои предположения неверны, но вот что я понимаю:

def received_messages
  # other stuff
  # we set @current_user to false <-- this is important
  @current_user = false
  # we are using tramp (async orm) this is not going to block the execution
  # of this method, so we will start executing this but we will also proceed
  # to the next step in this method (if statement after this)
  User.where(User[:id].eq("request.env['rack.session']['user_id']")).all method(:retrieve_current_user)
  # So the query is starting its execution but we are already at this if
  # statement and we execute the "wait_for_current_user" method and at this
  # point of time @current_user is still set to false <--- because of that
  # your wait_for_current_user method is printing "waiting for current user"
  # AND it returns false to this if statement <--- because of that we DO NOT
  # add the periodic timer (maybe change if to unless)
  if wait_for_current_user
    # we do not enter here because the wait_for_current_user returned false
    EM.add_periodic_timer(1) {wait_for_current_user}
  else
    # we go here and we execute "render false" which simply prints "false"
    render @current_user
    # at this point the query started on the User model might still be
    # running but here we go and execute the finish command and all you
    # get is "waiting for current_user false"
    finish
  end

Проблема в вашем методе условна.Прошу прощения за то, что не предоставил исправленную версию своего кода, но, надеюсь, вы сможете сами разобраться в этом, теперь, когда знаете, в чем ошибка.

...