2014-09-11 46 views
0

我對Ruby完全陌生,所以我的問題可能有一個相當簡單的答案。但是,我無法在stackoverflow上找到答案。 我有以下非常簡單的末日應用:Sinatra錯誤 - 繼續調用線程

# myapp.rb 
require 'rubygems' 
require 'sinatra' 
require 'json' 

range=(199..2000).step(1) 

set :port, 8888 

get '/hostname' do 
    content_type :json 
    return range.next.to_json 
end 

西納特拉開始:

ruby testsinatra.rb 
== Sinatra/1.0 has taken the stage on 8888 for development with backup from WEBrick 
[2014-09-11 08:43:18] INFO WEBrick 1.3.1 
[2014-09-11 08:43:18] INFO ruby 1.8.7 (2011-06-30) [x86_64-linux] 
[2014-09-11 08:43:18] INFO WEBrick::HTTPServer#start: pid=8215 port=8888 

和服務第一個請求:

curl -ks http://localhost:8888/hostname 
199 

但在第二個請求中的錯誤而失敗:

RuntimeError - 跨線程繼續調用:

/usr/lib/ruby/1.8/generator.rb:131:in `call' 
/usr/lib/ruby/1.8/generator.rb:131:in `next' 
/usr/lib/ruby/1.8/generator.rb:189:in `next' 
testsinatra.rb:30:in `GET /hostname' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:863:in `call' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:863:in `route' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:521:in `instance_eval' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:521:in `route_eval' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:500:in `route!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:497:in `catch' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:497:in `route!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:476:in `each' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:476:in `route!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:601:in `dispatch!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:411:in `call!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:566:in `instance_eval' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:566:in `invoke' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:566:in `catch' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:566:in `invoke' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:411:in `call!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:399:in `call' 
/usr/lib/ruby/gems/1.8/gems/rack-1.5.2/lib/rack/showexceptions.rb:24:in `call' 
/usr/lib/ruby/gems/1.8/gems/rack-1.5.2/lib/rack/methodoverride.rb:21:in `call' 
/usr/lib/ruby/gems/1.8/gems/rack-1.5.2/lib/rack/commonlogger.rb:33:in `call' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:979:in `call' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:1003:in `synchronize' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:1003:in `synchronize' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:979:in `call' 
/usr/lib/ruby/gems/1.8/gems/rack-1.5.2/lib/rack/handler/webrick.rb:60:in `service' 
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service' 
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run' 
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread' 
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start' 
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread' 
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start' 
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each' 
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start' 
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start' 
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start' 
/usr/lib/ruby/gems/1.8/gems/rack-1.5.2/lib/rack/handler/webrick.rb:14:in `run' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/base.rb:946:in `run!' 
/usr/lib/ruby/gems/1.8/gems/sinatra-1.0/lib/sinatra/main.rb:25 
testsinatra.rb:27 

很明顯,我錯過了一些基本的東西。請指教。

+0

任何原因,你使用一個古老的紅寶石版本與舊的sinatra版本。如果不是,我會建議升級到紅寶石2.1和Sinatra 1.4.5 – 2014-09-11 14:04:54

回答

0

測試代碼給出:

FiberError at /hostname 
fiber called across threads 

你可以在這裏找到一個相關的問題:Sharing an enumerator across threads。看起來Fiber代碼存儲了訪問該對象的第一個線程的ID,並在另一個線程嘗試這樣做時立即失敗。你顯然不能在線程之間共享枚舉器,並且必須採用不同的方法。

請注意,全局變量可能會被不同的線程同時訪問,您應該始終使用線程安全的對象或顯式鎖定。