2014-09-11 5 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

Любая причина, по которой вы используете действительно старую рубиновую версию со старой версией синатра. Если бы я не рекомендовал обновить до ruby ​​2.1 и sinatra 1.4.5 –

ответ

0

Тестирование кода дает:

FiberError at /hostname 
fiber called across threads 

Вы можете найти соответствующий вопрос здесь: Sharing an enumerator across threads. Кажется, что код Fiber хранит идентификатор первого потока, который сделал доступ к объекту, и сразу же терпит неудачу, когда другой поток пытается это сделать. Вы, по-видимому, просто не можете делиться счетчиками между потоками и должны прибегать к различным способам.

Также обратите внимание, что глобальные переменные могут быть доступны одновременно разными потоками, и вы всегда должны использовать поточно-безопасные объекты или явные блокировки.