2010-02-23 2 views
1

Следующие не работают. Вызов resource.next_document внутри потока возвращает nil. Тот же вызов без потоковой обработки работает, как ожидалось.Ruby, MongoDB: Как поделиться курсором между потоками?

Есть ли у специалистов MongoDB? : P

resources = db[Resource::COLLECTION].find 

    number_of_threads.times do 
    threads << Thread.new do 
     while resource = resources.next_document 
     puts 'one more doc' 
     end 
    end 
    end 

ответ

1

Хотя сам водитель поточно, люди курсора нет, поэтому вы не можете надежно обрабатывать данные в пути вы описываете.

Одна из возможностей состоит в том, чтобы иметь один поток, который выполняет итерацию по документам, передавая их любому количеству рабочих потоков для фактической обработки.

+0

Интересно ... Почему бы запрос быть запущен до или после нереста темы влияют на курсор по-разному, если курсор распределяется между все темы? – Alexandre

+0

kb: взгляните на мой ответ и скажите мне, что вы думаете – Alexandre

1

Это решение, которое я закончил с использованием:

Обратная связь Добро пожаловать

pool = DocumentPool.new(db) 
5.times do 
    Thread.new do 
    while doc = pool.next_document 
     #something cool 
    end 
    end 
end 


class DocumentPool 
    COLLECTION = 'some_collection' 

    def initialize(db) 
    @db = db     
    @first_doc = cursor.next_document  
    end 

    def collection 
    @db[COLLECTION] 
    end 

    def cursor 
    @cursor ||= collection.find 
    end 

    def shift 
    doc = nil 
    if @first_doc 
     doc = @first_doc 
     @first_doc = nil 
    else 
     doc = cursor.next_document  
    end 
    doc 
    end        

    def count 
    collection.count 
    end 
end 
+0

Это может сработать в некоторых ситуациях, но я не верю, что это безупречно. Для этого вам нужно синхронизировать метод next_document коллекции. –

+0

Почему метод next_document должен быть синхронизирован, но не мой собственный метод «сдвига» не будет? – Alexandre

+0

Я не уверен, что этот материал @first_doc имеет смысл. Все, что нужно сделать, это синхронизация вокруг вызова next_document. Кстати, в вашем примере кода в верхней части примера вы вызываете pool.next_document. Я думаю, вы имеете в виду pool.shift. –