在另外一篇文章中我们说到了Ruby中的循环引用及检查方法,循环引用在Ruby解析器看来只是一个警告,但是,这个告警会直接导致项目运行失败。
我就遇到了这个问题,被这个问题阻塞了好几天。下面详细看这个案例。
我有一个运行在ruby中的lighttpd程序。
lighttpd中的配置为:
fastcgi.debug = 1
fastcgi.server = ( ".rb" =>
((
"bin-path" => "~/uproject/utopia-project-code/main/source/server/service/pmu_service/lighttpd_stub.rb",
#"bin-path" => "~/uproject/utopia-project-code/main/source/server/service/pmu_service/test.rb",
#"bin-path" => "~/.rvm/rubies/ruby-1.9.3-p125/bin/ruby",
"socket" => "/tmp/ruby.socket",
"check-local" => "disable"
))
)
lighttpd_stub.rb代码为:
#!/usr/local/ruby/bin/ruby
require_relative './main_service'
#start....
pmu_server = PMU_Service::PMUServer.get_instance
pmu_server.start_fcgi
上面引用到的核心fcgi代码为:
require 'fcgi'
require 'json'
require_relative '../pmu_dao/dao'
require_relative '../pmu_service/user_service'
require_relative '../pmu_dao/db_conn_pool'
require_relative '../pmu_communication/comm8n'
require_relative '../pmu_common/common'
...
def start_fcgi
FCGI.each_request do |fcgi|
@logger.info("receive a request: ")
fcgi_out = fcgi.out
fcgi_in = fcgi.in
#fcgi_env = fcgi.env
fcgi_out.print "Content-Type: application/json"
#should be 2 /r/n, else will be error
fcgi_out.print "/r/n/r/n"
#post param is a json string
post_param = get_post_param(fcgi_in)
@logger.info("get the input param from client: /n" + post_param)
if post_param == nil || post_param.empty?
@logger.info("empty input param")
fcgi_out.print "the is the empty page."
fcgi_out.print "/r/n/r/n"
else
#the json string containing the Header and the content
#so parse the Header object from json first
header = JSON.parse(post_param["data"]["Header"])
#then create a Message object for the dispatcher
message = PMU_COMM8N::Message.new(header, post_param["data"]["Content"])
#after dispatch return the HandlerResult object
resp_msg = @msg_disp.dispatch_message(message)
#write result to client
fcgi_out.print resp_msg
fcgi_out.print "/r/n/r/n"
end
fcgi.finish
end
end
请注意最上面的好几个require_relative,这是引用项目中其他的ruby文件,现在问题就在,require_relative ‘../pmu_service/user_service’,有循环引用的问题,通过 ruby -w 执行会输出如下警告:
~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6: warning: loading in progress, circular require considered harmful - ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb
from main_service.rb:7:in `
from main_service.rb:7:in `require_relative'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb:7:in `
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_service.rb:7:in `require_relative'
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6:in `
from ~/uproject/utopia-project-code/main/source/server/service/pmu_service/user_handler.rb:6:in `require_relative'
上面这个警告,要是真把其当作一个警告而忽略的话,就酿成大错了。
我的lighttpd的fcgi每次处理请求的时候,就会报如下错误:
`block in start_fcgi': undefined method `[]' for nil:NilClass (NoMethodError)
错误对应的行是:
FCGI.each_request do |fcgi|
意思是FCGI.each_request里面本身出问题了。
这个问题很怪异,但是修正循环引用后问题就消失了。所以循环引用对于应用层代码来说,就是一个bug。
本文链接:http://www.yunweipai.com/519.html
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/53131.html