2016-09-08 3 views
1

Я пытаюсь интегрировать Lucene в веб-приложение. (. Не для полнотекстового индексирования, но для быстрого поиска и сортировки) Я создал службу:Интеграция 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, запустив его в конструкторе вашего (singleton) 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 = ??? 
} 
Смежные вопросы