【问题标题】:Integrating Lucene in play framework在游戏框架中集成 Lucene
【发布时间】:2016-09-08 10:24:57
【问题描述】:

我正在尝试将 Lucene 集成到 Web 应用程序中。 (不是为了全文索引,而是为了快速搜索和排序。)我创建了一个服务:

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。玩 2.5.x,scala 2.11.8

【问题讨论】:

  • 您是否在完成后关闭IndexWriter 实例?这是necessary to release the write lock。如果您想保持索引编写器打开并在关闭时将其关闭,请将 Lifecycle 实例注入您的 ConcreteIndex 并添加关闭挂钩以关闭编写器。
  • 成功了。谢谢@Mikesname。您能回答一下,以便我将其标记为已解决吗?

标签: playframework dependency-injection lucene


【解决方案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 = ???
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 2011-11-09
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    相关资源
    最近更新 更多