Ich habe, was ich denke, muss ein Nebenläufigkeitsproblem sein. Ich benutze Passagier, Schienen 2.3.5, Mongoid 1.9.2 und Mongo Ruby-Treiber 1.0.9. Ich verwende jQuery, um Daten anzufordern, die aus MongoDB abgerufen und dann im Browser gerendert werden. Alles funktioniert gut, bis ich anfing, zwei solche Anfragen gleichzeitig zu machen. In dem Modell, das sind die Methoden, die von den Anfragen ausgeführt werden soll:Ruby Mongo oder Mongoid Concurrency Problem
Class Visit
include Mongoid::Document
...
def self.cancellations_and_visits_by_therapist_graph(clinic_id)
visits = collection.group("function(x){ return { resource_id : x.resource_id } }",
{:clinic_id => clinic_id, :visit_date => { "$gte" => Time.now - 6.months, "$lte" => Time.now}},
{:visits => 0, :cancel_no_shows => 0},
'function(obj, count) {
if (obj.visit_status == "NO SHOW" || obj.visits_status == "CANCELLED") {
count.cancel_no_shows += 1;
} else {
count.visits += 1;
}
}')
visits = visits.group_by {|g| g['resource_id']}
Resource.any_in(:mysql_id => visits.keys).order_by([:last_name, :asc]).order_by([:first_name, :asc]).inject({ 'visits' => [], 'cancel_no_shows' => [], 'xlabels' => []}) do |formatted_visits, resource|
formatted_visits['visits'] << visits[resource.mysql_id.to_f].first['visits']
formatted_visits['cancel_no_shows'] << visits[resource.mysql_id.to_f].first['cancel_no_shows']
formatted_visits['xlabels'] << resource.last_name + ", " + resource.first_name
formatted_visits
end
end
def self.total_visits_for_graph(practice_id)
visits = collection.group("function(x) { return { clinic_id : x.clinic_id } }",
{:practice_id => practice_id, :visit_status => 'COMPLETE', :visit_date => { "$gte" => Time.now - 6.months, "$lte" => Time.now}},
{:visits => 0}, "function(obj, count) { count.visits += 1; }")
visits = visits.group_by {|g| g['clinic_id']}
Clinic.any_in(:mysql_id => visits.keys).order_by([:name, :asc]).inject({ 'data' => [], 'xlabels' => []}) do |formatted_visits, clinic|
formatted_visits['data'] << visits[clinic.mysql_id.to_f].first['visits']
formatted_visits['xlabels'] << clinic.name
formatted_visits
end
end
end
Der beste Weg, um das Problem zu beschreiben, ist, dass die Ergebnisse von Mongo sind mit dem falschen Objekt übergeben zu werden. Ich lookated ein Beispiel dafür:
Dies wurde zurückgegeben, als ich CLinic.any_in genannt (es ist ein Ergebnis aus einer der Gruppen):
{"group"=>{"$keyf"=>"function(x){ return { resource_id : x.resource_id } }", "cond"=>{:clinic_id=>101, :visit_date=>{"$gte"=>Tue Apr 20 15:34:37 +0800 2010, "$lte"=>Wed Oct 20 15:34:37 +0800 2010}}, "ns"=>"visits", "initial"=>{:visits=>0, :cancel_no_shows=>0}, "$reduce"=>"function(obj, count) {\n if (obj.visit_status == \"NO SHOW\" || obj.visits_status == \"CANCELLED\") {\n count.cancel_no_shows += 1;\n } else {\n count.visits += 1;\n }\n\n }"}}
Das (eine Klinik Objekt) wurde durch die Sammlung zurückgegeben .group nennen:
{"_id"=>BSON::ObjectId('4cb7d72b3bc5457800ce2e6f'), "name"=>"Corona", "practice_id"=>39, "mysql_id"=>101}
Wie bei allen guten concurancy Probleme die Ergebnisse sind randome, manchmal funktioniert es gut und manchmal bläst sie nach oben. Ich bin neu bei Mongo und Mongoid, also bin ich mir eigentlich nicht sicher, ob das ein Problem mit Mongoid oder dem Mongo Driver ist, aber ich denke es ist mit Mongoid verwandt. Ich nehme meinen Initialisierer mit, den ich verwende, um Mongoid in Schienen zu laden. Irgendwelche Ideen oder sogar nur zusätzliche Debugging-Ideen sind sehr zu schätzen.
Anschluss
mongoid_conf = YAML::load_file(Rails.root.join('config/mongoid.yml'))[Rails.env]
Mongoid.configure do |config|
config.master = Mongo::Connection.new(mongoid_conf['host'], 27017, :pool_size => 5, :timeout => 5).db(mongoid_conf['database'])
end