2015-12-10 1 views
0

Je développe une application WPF qui utilise Lucene.Net pour indexer des données à partir de fichiers générés par un processus tiers. C'est un faible volume avec de nouveaux fichiers créés pas plus d'une fois par minute.Plusieurs instances d'application utilisant Lucene.Net

Mon application utilise une instance singleton IndexWriter créée au démarrage. De même, un IndexSearcher est également créé au démarrage, mais il est recréé chaque fois qu'un IndexWriter.Commit() se produit, garantissant que les nouveaux documents apparaîtront dans les résultats de la recherche.

Quoi qu'il en soit, certains utilisateurs doivent exécuter deux instances de l'application, mais le problème est que les documents nouvellement ajoutés n'apparaissent pas lors de la recherche dans la seconde instance. Je suppose que c'est parce que la première instance fait les commits, et il doit y avoir un moyen de dire à la deuxième instance de recréer son IndexSearcher. Une façon serait de signaler cela en utilisant un fichier create/update en conjonction avec un FileSystemWatcher, mais je me demandais d'abord s'il y avait quelque chose dans Lucene.Net que je pourrais utiliser?

Répondre

2

La seule chose que je peux penser à qui pourrait vous être utile est IndexReader.Reopen(). Cela va actualiser le IndexReader, mais seulement si l'index a changé depuis que le lecteur a été ouvert à l'origine. Il devrait provoquer un accès minimal au disque dans le cas où l'index n'a pas été mis à jour, et dans le cas où il l'a fait, il essaie de charger uniquement les segments qui ont été modifiés ou ajoutés. Une chose à noter à propos de l'API: Reopen renvoie IndexReader. Dans le cas où l'index n'a pas changé, il renvoie la même instance; sinon il en retourne un nouveau. Le lecteur d'index d'origine n'est pas disposé, de sorte que vous devrez le faire manuellement:

IndexReader reader = /* ... */; 
IndexReader newReader = reader.Reopen(); 

if(newReader != reader) 
{ 
    // Only close the old reader if we got a new one 
    reader.Dispose(); 
} 

reader = newReader; 

je ne peux pas trouver la documentation .NET en ce moment, mais here are the Java docs pour Lucene 3.0.3 qui expliquent l'API.

1

Si les deux instances ont leur propre IndexWriter ouvert sur le même répertoire, vous êtes dans un monde de douleur et de mauvais comportement intermittent. Un IW attend et requiert un contrôle exclusif du répertoire d'index. C'est la raison du fichier de verrouillage.

Si la deuxième instance peut détecter qu'il existe une instance existante, alors vous pourriez simplement ouvrir un IndexReader/Searcher sur le dossier et rouvrir lorsque le répertoire change.

Mais que se passe-t-il si la première instance se ferme? L'index ne sera plus mis à jour. La seconde instance aurait donc besoin de se réinitialiser, cette fois avec un IW. Peut-être qu'il pourrait le faire lorsque le fichier de verrouillage est supprimé lorsque la première instance se ferme. La meilleure approche serait de faire tourner un "service" (juste un processus d'arrière-plan, peut-être dans la barre d'état système). Toutes les instances de l'application interrogeraient ce service. Si l'application est démarrée et que le service n'est pas détecté, lancez-le.