导致ajax超时的Rails观察者

时间:2015-09-16 14:37:37

标签: ruby-on-rails activerecord callback observers faye

我已经创建了一个观察员来发送"通知"在ROR 4中使用faye服务器的消息。在我的localhost上开发工作正常但在我的EC2上正在生产中观察者在某些时候失败了,我无法理解,它阻止活动观察要保存的记录。

以下是我的观察员:

class NotificationObserver < ActiveRecord::Observer

require 'eventmachine'



def after_save(notification)
@user = '2'
@channel = '/notifications/2'
@count = '0'

    EM.run {

        client = Faye::Client.new('http://domain.com:9292/faye')    

        publication = client.publish( @channel , {'noti' => 'hello world', 'count' => '0' } )



        publication.callback do
          puts 'Message received by server!'
        end

        publication.errback do |error|
          puts 'There was a problem: ' + error.message
        end


}



end

end

我已经阅读了有关回调问题的信息,但在开发过程中工作正常并且我已经测试了“发布”问题。 rails控制台内部的动作通过回调发送通知,并且成功。 我也尝试在应用程序的副本中从localhost连接到ec2的ec2实时服务器,它按预期工作,我们也可以丢弃faye服务器。

所以它必须与de after_save触发器相关。我无法理解的是,为什么要阻止记录被保存,因为它是一个事后触发器。它应该在保存记录后开始执行,对吗?

在localhost中,我在ubuntu 14中使用apache2 + thin,在我的ec2中使用nginx和unicorn运行应用程序,在ubuntu 14中也是如此。可能是我错过了一些不同于apache2&amp; /或thin的独角兽或nginx配置。

更新:[通知现在正在保存,但是ajax以超时结束]

根据我从@ lazus-lazaritis链接中学到的知识,我已经改变了#su_save&#39; for&#39; after_commit&#39;并且如果有任何错误,请使用记录器代替put来捕获响应。现在通知已保存并且&#34; publication.callback&#34;取得成功,我得到了#34; a-ok&#34;在日志中,但是由触发所有操作的表单打开的ajax连接仍然以504网关超时结束。

这里是更新后的观察员:

class NotificationObserver < ActiveRecord::Observer

require 'eventmachine'



def after_commit(notification)
    @user = '2'
    @channel = '/notifications/2'
    @count = '0'

        EM.run {

            client = Faye::Client.new('http://domain.com:9292/faye')



            publication = client.publish( @channel , {'noti' => 'hola', 'count' => '0' } )



            publication.callback do
              Rails.logger.debug("a-ok")
            end

            publication.errback do |error|
              Rails.logger.error( 'There was a problem: ' + error.message)
            end


    }



end

这是控制器

def create
    @article = Article.find(params[:article_id])
    @like = current_user.likes.build(article_params)
    @user_id = current_user.id

    if @like.save

        @notification = Notification.new(user_id: @article.user.id, stype: 'like_article', actor_id: @user_id, action_id: @like.id)
        @notification.save                          
        respond_to do |format|
            format.html { redirect_to @article }
            format.js
        end

    else
        flash[:success] = "Ya te gusta!"
        redirect_to @article
    end
end

如果出现以下情况,我无法理解为什么ajax会以超时响应:

  • 观察员开火前的所有进程都已完成,通知保存之前也失败了。
  • 观察者中的EM.run在production.log中登录ok响应,因此回调正常工作after_commit

我错过了什么?

这是unicorn.stderr日志:

  

E,[2015-09-16T17:56:40.096133#15731]错误 - :worker = 1 PID:16910超时(61s> 60s),杀死

     

E,[2015-09-16T17:56:40.102198#15731]错误 - :收获#worker = 1

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您的后回调引发异常,请阅读以下内容:

  

整个回调链包含在一个事务中。如果在回调方法之前返回任何错误或引发异常,则执行链将停止并发出ROLLBACK;回调之后只能通过引发异常来实现。

http://guides.rubyonrails.org/active_record_callbacks.html