Nous avons un site Web en cours d'exécution dans Windows Server 2008 + SQLServer 2008 + Ruby + Sinatra + Sequel/PumaSequel + ADO + Puma n'est pas de filetage des requêtes
Nous avons développé une API pour notre site Web. Lorsque les points d'accès sont demandés par plusieurs clients, en même temps, les clients commencent à recevoir des exceptions RequestTimeout. J'ai étudié un peu, et j'ai noté que Puma gère très bien le multi-threading. Mais Sequel (ou n'importe quelle couche sous Sequel) traite une requête à la fois, même si elles proviennent de clients différents. En fait, les exceptions RequestTimeout ne se produisent pas si je lance de nombreux serveurs Web, chacun écoute un port différent et j'affecte un port différent à chaque client.
Je ne sais pas encore si le problème est Sequel, ADO, ODBC, Windows, SQL Server ou quoi. La vérité est que je ne peux pas passer à toute autre technologie (comme TinyTDS)
Bellow est un petit morceau de code avec des captures d'écran que vous pouvez utiliser pour reproduire le bug:
require 'sinatra'
require 'sequel'
CONNECTION_STRING =
"Driver={SQL Server};Server=.\\SQLEXPRESS;" +
"Trusted_Connection=no;" +
"Database=pulqui;Uid=;Pwd=;"
DB = Sequel.ado(:conn_string=>CONNECTION_STRING)
enable :sessions
configure { set :server, :puma }
set :public_folder, './public/'
set :bind, '0.0.0.0'
get '/delaybyquery.json' do
tid = params[:tid].to_s
begin
puts "(track-id=#{tid}).starting access point"
q = "select p1.* from liprofile p1, liprofile p2, liprofile p3, liprofile p4, liprofile p5"
DB[q].each { |row| # this query should takes a lot of time
puts row[:id]
}
puts "(track-id=#{tid}).done!"
rescue=>e
puts "(track-id=#{tid}).error:#{e.to_s}"
end
end
get '/delaybycode.json' do
tid = params[:tid].to_s
begin
puts "(track-id=#{tid}).starting access point"
sleep(30)
puts "(track-id=#{tid}).done!"
rescue=>e
puts "(track-id=#{tid}).error:#{e.to_s}"
end
end
Il y a 2 points d'accès dans le code ci-dessus:
delaybyquery.json, qui génère un retard en se joignant à la même table 5 fois. Notez que la table doit contenir environ 1000 lignes pour que la requête fonctionne très lentement; et
delaybycode.json, qui génère un retard en appelant simplement la fonction sommeil rubis .
Les deux points d'accès reçoit un paramètre tid (suivi-id), et les deux écrivent le outout dans le CMD, afin que vous puissiez suivre l'activité des deux processus dans la même fenêtre et vérifiez le point d'accès est bloquer les demandes entrantes provenant d'autres navigateurs .
Pour tester, j'ouvre 2 onglets dans le même navigateur chrome. Voici les 2 tests que j'effectue.
Étape 1: Lancez le serveur Web
c: \ source de \ Pulqui> Ruby example.app.rb -p 81 Je reçois la sortie ci-dessous
Étape # 2: Retard d'essai par le code
J'ai appelé à l'adresse suivante: 127.0.0.1:81/delaybycode.json?tid=123 et 5 secondes plus tard, j'appelle cette autre URL 127.0.0.1:81/delaybycode.json?tid = 456 Ci-dessous la sortie, où vous pouvez voir que les deux appels travaillent en parallèle
click here to see the screenshot
Étape # 3: Retard d'essai par Query
J'ai appelé à l'adresse suivante: 127.0.0.1:81/delaybyquery.json?tid=123 et 5 secondes plus tard, j'ai appelé cette autre URL 127.0.0.1:81/delaybyquery.json?tid=456 Ci-dessous est la sortie, où vous pouvez voir que les appels sont travaillant 1 à l'heure. Chaque appel à un point d'accès se termine par une exception de délai d'attente de requête.
click here to see the screenshot
S'il vous plaît, cliquez sur les liens pour voir les captures d'écran. Toutes mes excuses, mais StackOverflow ne me permet pas encore de publier des images. –