I have the following little Sinatra program. It simply prints the current epoch time and then sleeps for one second before returning:
require 'rubygems'
require 'sinatra'
get '/' do
Thread.new do
$mutex.synchronize do
stream do |out|
out << "\n" << Time.now.to_i
sleep 1
end
end
end.join
end
$mutex = Mutex.new
I would expect the mutex to force the web requests to be handled sequentially. However, this does not seem to be the case according to this test:
$ for i in $(seq 5) ; do curl localhost:4567/ & disown; done
1378839480
1378839480
1378839480
1378839480
1378839480
As you can see, the result of five simultaneous requests all produce the same epoch time.
What am I doing wrong?
Sinatra has a single request concurrency lock option:
require 'rubygems'
require 'sinatra'
set :lock, true
get '/' do
time = Time.now.to_i
sleep 1
time.to_s
end
I think I figured it out. The stream call starts a background job which returns immediately. So the mutex is unlocked quickly, allowing a new request to be processed.
Moving the code outside of the stream block fixes it:
get '/' do
Thread.new do
$mutex.synchronize do
result = "\n" + Time.now.to_i
sleep 1
stream do |out|
out << result
end
end
end.join
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.