【发布时间】:2013-12-30 21:28:40
【问题描述】:
我有一个简单的 Sinatra 应用程序,其中包含一条长时间运行的路线:
get '/jobs/new' do
logger.info "jobs/new start. Thread = #{Thread.current.inspect}"
sleep 10
logger.info "end new..."
erb :'jobs/new'
end
get '/jobs' do
erb :'jobs/index'
end
我可以同时访问多个路由,但不能访问同一条路由。
一个例子是,当一个客户端调用/jobs/new(长时间访问)时,另一个客户端可以并行调用jobs。但是对同一条路线的并行调用不起作用。在这种情况下,网络服务器 Puma 总是使用同一个线程调用路由:
jobs/new started. Thread = #<Thread:0x007f42b128e600 run>
10 seconds later...
jobs/new ended. Thread = #<Thread:0x007f42b128e600 run>
jobs/new started. Thread = #<Thread:0x007f42b128e600 run> <-- new call. Has to wait till first has finished
另一个路由被不同的线程调用。在路线 1 运行时:
jobs/new started. Thread = #<Thread:0x007f42b128e600 run>
2 seconds later...
jobs started. Thread = #<Thread:0x007f541f581a40 run> <--other thread
8 seconds later...
jobs/new ended. Thread = #<Thread:0x007f42b128e600 run>
jobs/new started. Thread = #<Thread:0x007f42b128e600 run>
我尝试在线程模式下使用 Thin 和 Puma 以相同的行为运行应用程序
【问题讨论】:
-
没有必要,也不建议在标题中添加关键字,除非它们是标题正常句子结构的一部分。搜索不使用诸如“Sinatra:”之类的关键字,它们也无助于问题的关键工作排名。相反,它们降低了标题的可读性。关键字和搜索基于您添加到问题的标签。
标签: ruby concurrency sinatra thin puma