2016-09-08 6 views
1

私はLuceneをWebアプリケーションに統合しようとしています。 (未フルテキストインデックス作成のために、しかし、クイック検索用およびソート。)私は、サービスを作成しました:再生フレームワークでのLuceneの統合

trait Index { 
    def indexAd(a: Ad): Unit 
} 

@Singleton 
class ConcreteIndex @Inject()(conf: Configuration) extends Index { 
    val dir =  FSDirectory.open(FileSystems.getDefault.getPath(conf.getString("index.dir").get)) 
    val writer = new IndexWriter(dir, new IndexWriterConfig(new StandardAnalyzer)) 
    override def indexAd(a: Ad): Unit = { 
     val doc = new Document 
     ... 
    } 
} 

とコントローラでそれを使用しよう:

@Singleton 
class AdsController @Inject()(cache: CacheApi, index:Index) extends Controller { 
    ... 
} 

をしかし、注入は成功しません。私は、ロックファイルを削除して、もう一度新鮮実行しようとした

Error injecting constructor, org.apache.lucene.store.LockObtainFailedException: 
Lock held by this virtual machine: .../backend/index/write.lock 

を得ました。それでも同じ例外がスローされます。誰も私にこれを手伝ってもらえますか?私はLucene 6.2.0を使用しています。 Play 2.5.x、scala 2.11.8

+0

で終わったら 'IndexWriter'インスタンスを終了していますか?書き込みロックを解除する必要があります(https://lucene.apache.org/core/6_1_0/core/org/apache/lucene/index/IndexWriter.html#close--)。インデックスライターを開いたままにしてシャットダウンするときは、 'Lifecycle'インスタンスを' ConcreteIndex'に注入し、ライターを閉じるためのシャットダウンフックを追加してください。 – Mikesname

+0

それは働いた。ありがとう@Mikesname。私はそれを解決済みとすることができるように答えることができますか? – yang

答えて

1

ロックを解除するには、シャットダウン時にIndexWriterが閉じていることを確認する必要があります。これは高価な操作である可能性があります。したがって、インデックス作成者のライフサイクルをPlayアプリケーションのライフサイクルと結びつけ、(シングルトン)ConcreteIndexインスタンスのコンストラクタで開始し、注入されたApplicationLifecycleにストップフックを追加してシャットダウンしますインスタンス。例:

@ImplementedBy(classOf[ConcreteIndex]) 
trait Index { 
    def index(s: String): Unit 
} 

@Singleton 
case class ConcreteIndex @Inject()(conf: Configuration, 
            lifecycle: play.api.inject.ApplicationLifecycle) extends Index { 

    private val dir = FSDirectory.open(FileSystems.getDefault.getPath(conf.getString("index.dir").get)) 
    private val writer = new IndexWriter(dir, new IndexWriterConfig(new StandardAnalyzer())) 

    // Add a lifecycle stop hook that will be called when the Play 
    // server is cleanly shut down... 
    lifecycle.addStopHook(() => scala.concurrent.Future.successful(writer.close())) 

    // For good measure you could also add a JVM runtime shutdown hook 
    // which should be called even if the Play server is terminated. 
    // If the writer is already closed this will be a no-op. 
    Runtime.getRuntime.addShutdownHook(new Thread() { 
    override def run() = writer.close() 
    }) 

    def index(s: String): Unit = ??? 
} 
関連する問題