2

Okay i have code that using Cramp\Tramp => EventMachine under the hood. Code:

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

I need results from the query to continue execution in controller action, but it looks like execution finished before i get data. Rendered text is:

waiting for current_user false

my gemfile is:

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 Answers1

1

I haven't used Cramp/Tramp, so sorry if my assumptions are incorrect but here is what is going on from what I can understand:

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

The problem is in conditional in your method. I'm sorry for not giving the fixed version of your code but hopefully you can figure it out yourself now that you know where the error is.