Je suis en train de réaliser quelque chose comme ça dans MonogDB:Blocage findAndModify en Ruby MongoDB pilote
require 'base64'
require 'mongo'
class MongoDBQueue
def enq(thing)
collection.insert({ payload: Base64.encode64(Marshal.dump(thing))})
end
alias :<< :enq
def deq
until _r = collection.find_and_modify({ sort: {_id: Mongo::ASCENDING}, remove: true})
Thread.pass
end
return Marshal.load(Base64.decode64(_r["payload"]))
end
alias :pop :deq
private
def collection
# database, collection & mongodb index semantics here
end
end
assez Je veux naturellement une file d'attente de disque soutenu par Ruby qui ne détruit pas ma mémoire disponible, je Si je l'utilise avec le framework Anemone Web Spider qui utilise par défaut la classe Queue
, il y a une fourchette qui peut utiliser la classe SizedQueue
, mais en utilisant un SizedQueue
pour la "queue de page" et la "file d'attente de liens", il est souvent deadlocks, vraisemblablement parce qu'il essaie de défaire une page et de la traiter, et il a trouvé de nouveaux liens, et cette situation ne peut pas être réconciliée.
Il y a aussi une implémentation existante d'une file d'attente Redis, mais qui épuise aussi toute ma mémoire disponible sur cette machine (mémoire disponible est de 16 Go, il est donc pas trivial)
En raison de ce que je veux utiliser ce backend MongoDB , mais je pense que la mise en œuvre est folle. Le Thread.pass
ressemble à une solution horrible, mais Anemone est multi-thread, et MongoDB ne supporte pas les lectures bloquantes, donc c'est une situation délicate.
Voilà mes références:
Redis mise en œuvre de file d'attente pour anémone: https://github.com/chriskite/anemone/blob/queueadapter/lib/anemone/queue/redis.rb
MongoDB findAndModify: http://www.mongodb.org/display/DOCS/findAndModify+Command
Questions:
- Quelqu'un peut-il commenter sur la façon saine d'esprit est ce, par rapport à
sleep
(qui devrait déclencher la machine virtuelle pour passer le contrôle au fil suivant, de toute façon, maissleep
se sent plus sale) - Dois-je peut-être
Thread.pass
etsleep
? (Je suppose que non, voir ci-dessus) - Puis-je faire lire le bloc MongoDB? On en a parlé ici, mais cela n'est jamais arrivé à rien: https://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/rqnHNFXaZ0w
Qu'est-ce qui vous fait penser que MongoDB ne supporte pas les lectures bloquantes? Si vous faites un find_one() ou un find_and_modify(), l'opération ne retournera pas tant que la requête n'est pas terminée et que le résultat est de retour sur le client. Vous aurez besoin de faire des écritures "Safe Mode" afin d'avoir des écritures bloquantes. –
William, comment pourrait-on changer le code ci-dessus pour être une lecture bloquante?(Je définis le blocage comme ne retournant pas jusqu'à ce qu'un résultat satisfasse la requête) –
simplement faire >> jusqu'à _r = collection.find_and_modify ({sort: {_id: Mongo :: ASCENDING}, enlever: vrai}) << devrait bloquer - juste dans ce fil, bien sûr –