前段时间用 faye 为系统添加了即时聊天的功能,faye server 被打包进 rack application, 通过/config/initializers/faye.rb
, 使用 thin 随 rails 一同启动。
之后客户追加新功能,需要对未在线用户,如果有新的聊天信息,要对其进行提醒
因为要兼顾 IE 用户,未使用 faye websocket. 所以判断用户是否在线采取的策略是:
标记在线/离线时候,使用到了 ActiveRecord 的 model, 而 model 里又用到了位于 vendor/plugins/下的 gem, acts_as_paranoid.
于是在 rack 里面一顿 require, 总算是在本地能跑起来 (development 下的 thin/webrick, production 下 apache+passenger)
但是部署到服务器之后,发现 thin 启动不起来,报错说找不到destroy_without_callbacks
方法
又折腾了好半天没什么结果,恳请大家帮我看下是哪儿出了问题,非常感谢。
thin 启动失败的报错信息
/home/college-dev/rails/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb:56:in `alias_method': undefined method `destroy_without_callbacks' for class `UserChatTeam' (NameError)
from /home/college-dev/rails/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb:56:in `acts_as_paranoid'
from /home/college-dev/rails/app/models/user_chat_team.rb:2
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /usr/lib/ruby/gems/1.8/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `require'
from /usr/lib/ruby/gems/1.8/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:223:in `load_dependency'
from /usr/lib/ruby/gems/1.8/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:640:in `new_constants_in'
from /usr/lib/ruby/gems/1.8/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:223:in `load_dependency'
from /usr/lib/ruby/gems/1.8/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `require'
from faye.ru:14
from /usr/lib/ruby/gems/1.8/gems/rack-1.3.6/lib/rack/builder.rb:51:in `instance_eval'
from /usr/lib/ruby/gems/1.8/gems/rack-1.3.6/lib/rack/builder.rb:51:in `initialize'
from faye.ru:1:in `new'
from faye.ru:1
faye.ru 的内容
require 'faye'
require File.expand_path('../config/initializers/faye_token.rb', __FILE__)
require 'active_record'
require 'mysql'
require 'yaml'
# using 'acts_as_paranoid' as a plugin in 'vendor/plugins'
RAILS_ENV = ENV['RACK_ENV']
load 'active_record/associations.rb'
require File.expand_path('../vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb', __FILE__)
require File.expand_path('../vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb', __FILE__)
require File.expand_path('../vendor/plugins/acts_as_paranoid/lib/caboose/acts/has_many_through_without_deleted_association.rb', __FILE__)
require File.expand_path('../vendor/plugins/acts_as_paranoid/init.rb', __FILE__)
require File.expand_path('../app/models/user_chat_team.rb', __FILE__)
environment = ENV['RACK_ENV'] || 'production'
dbconfig = YAML.load(File.read('config/database.yml'))
ActiveRecord::Base.establish_connection(dbconfig[environment])
class ServerAuth
def incoming(message, callback)
if message['channel'] !~ %r{^/meta/}
if message['ext']['auth_token'] != FAYE_TOKEN
message['error'] = 'Invalid authentication token.'
else
message['ext'].delete('auth_token')
end
end
callback.call(message)
end
end
class MarkOnline
def incoming(message, callback)
if message['channel'] == '/meta/subscribe'
UserChatTeam.mark_online( message['data']['user_id'],
message['data']['chat_team_id'],
message['clientId'])
end
callback.call(message)
end
end
faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 45)
faye_server.add_extension(ServerAuth.new)
faye_server.add_extension(MarkOnline.new)
faye_server.on('unsubscribe') do |client_id, channel|
UserChatTeam.mark_offline(client_id)
end
faye_server.on('disconnect') do |client_id|
UserChatTeam.mark_offline(client_id)
end
run faye_server
faye.rb 的内容
# 随rails一起启动faye server
Thread.new do
system("thin -C #{RAILS_ROOT}/config/faye.ym l start")
end
require 'yaml'
# もしキーが存在しなかったら例外を投げる様にする。
FAYE_CONFIG = Hash.new{|hash, key| raise(IndexError, "no such key : [#{key}] !!")}
FAYE_CONFIG.merge!(YAML.load(File.open(RAILS_ROOT + '/config/faye.yml')))
FAYE_CONFIG.each do |k,v|
if v.is_a?(Hash)
v.replace(Hash.new{|hash,key| raise(IndexError, "no such a key in FAYE_CONFIG : #{key} !!")}.merge(v))
end
end
# FAYE_CONFIGのキーが全てSymbolで指定してあるかチェック
# Symbol以外の値は不正なので、例外を出して起動を中止する。
def faye_config_valid?(hash)
hash.each do |k,v|
unless k.is_a?(Symbol)
# Railsの仕様で、environment.rb で例外を出しても起動してしまうが、
# gem の読み込みエラーのみ停止してくれるので、仕方なくそれを利用する。
# 詳細は config/boot.rb を参照のこと。
require '/config/faye.yml のキーは全てシンボルでなければいけません。'
end
case
when v.is_a?(Hash) # Hashならば、再帰処理
faye_config_valid?(v)
when v.is_a?(String) # Stringならば、{RAILS_ROOT}を実際の値に書き換える.
v.sub!(/\{RAILS_ROOT\}/, RAILS_ROOT)
end
end
end
faye_config_valid?(FAYE_CONFIG)
# Don't Comment out!!
FAYE_CONFIG.freeze