2010-10-20 15 views
5

Bir eş zamanlılık sorunu olması gerektiğini düşündüğüm şeyi yaşıyorum. Ben yolcu, ray 2.3.5, mongoid 1.9.2 ve Mongo yakut sürücüsü 1.0.9 kullanıyorum. MongoDB'den çekilen ve daha sonra tarayıcıda oluşturulan verileri istemek için jQuery kullanıyorum. Aynı anda iki istekte bulunana kadar her şey harika çalışıyor. modelde bu isteklere göre idam yöntemleri şunlardır:Ruby Mongo veya Mongoid eşzamanlılık sorunu

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 

sorunu açıklamak için en iyi yol Mongo sonuçları yanlış nesneye geçirilen alıyorsanız olmasıdır.

{"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   }"}} 

Bu (bir klinik nesnesi) koleksiyonu ile döndürüldü:

I CLinic.any_in olarak adlandırılan bu döndürüldü

(bu grubun birinden bir sonucudur): Bu bir örneğini lookated sonuçlar randome olan tüm iyi concurancy sorunları gibi

{"_id"=>BSON::ObjectId('4cb7d72b3bc5457800ce2e6f'), "name"=>"Corona", "practice_id"=>39, "mysql_id"=>101} 

bazen çalışıyor, bazen de havaya uçuran: .group diyoruz. Ben mongo ve mongoid için yeniyim, bu yüzden mongoid veya mongo sürücüsü ile ilgili bir sorun olup olmadığından emin değilim, ancak Moğolla ilgili olduğunu düşünüyorum. Mongoid'i raylara yüklemek için kullanıyorum başlatıcımı ekliyorum. Herhangi bir fikir, hatta sadece ek hata ayıklama fikirleri büyük önem taşıyor.

Bağlantı

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 

cevap

5

Ben bu soruna çözüm buldu. Aslında Mongo sürücüsü ya da Mongoid değildi, yolcuydu. Yolcu rayları işler hale getirdiğinde, geçerli örneği sorar, böylece dosya tanıtıcıları (TCP tanımlayıcıları uygulama örnekleri arasında paylaşılır). Bu, mongo'nun aynı soket tarafından yazıldığı ve okunacağı anlamına gelir, bu da eşzamanlılık sorununa yol açan şeydir. Çözüm, çatal uçları ne zaman olursa olsun tekrar bağlantı kurmaktır. Orijinal cevap gönderme ve tartışma için

# Handle the creation of new processes by Phusion Passenger 
if defined?(PhusionPassenger) 
    PhusionPassenger.on_event(:starting_worker_process) do |forked| 
    if forked 
     # We're in smart spawning mode. 

     # Reset the connection to MongoDB 
     Mongoid.config.master.connection.close 
     load File.join(RAILS_ROOT, 'config/initializers/mongoid_init.rb') 
    else 
     # We're in conservative spawning mode. We don't need to do anything.  
    end 
    end 
end 

Referans http://groups.google.com/group/mongodb-user/browse_thread/thread/f31e2d23de38136a: Bu buldum çözümdür.