gmethvin / directory-watcher

A cross-platform Java recursive directory watcher, with a JNA macOS watcher and Scala better-files integration
Apache License 2.0
265 stars 34 forks source link

How to run the watcher? #25

Closed simon-gunacker closed 5 years ago

simon-gunacker commented 5 years ago

I am trying to run the watcher in Scala. But even though I am calling watcher.start() (which i expect to run forever), the program finishes immediately. What am I doing wrong?

import better.files._
import io.methvin.better.files._
import scala.concurrent.ExecutionContext.Implicits.global

object FileWatcher
{

  def main(args: Array[String]): Unit =
  {
    val myDir = File("/path/to/dir")
    val watcher = new RecursiveFileMonitor(myDir)
    {
      override def onCreate(file: File, count: Int) = println(s"$file got created")

      override def onModify(file: File, count: Int) = println(s"$file got modified $count times")

      override def onDelete(file: File, count: Int) = println(s"$file got deleted")
    }

    watcher.start()
  }

}
gmethvin commented 5 years ago

start() works exactly like it does in the better-files File.Monitor it extends. It doesn't block. It runs the watch thread on the global execution context you've provided implicitly. The issue you're seeing is that your program is finishing immediately after the watcher starts running in the background.

simon-gunacker commented 5 years ago

Yes. Non-blocking is a good thing for a file monitor ;-). But how can I run my program then? Let's just assume that it should not do anything else than printing the events ...

gmethvin commented 5 years ago

The Scala global execution context sets threads to be daemon threads. The JVM will be shut down when all non-daemon threads have exited, so as soon as your main thread finishes, your watcher will be terminated. You either need some other non-daemon thread running doing your processing, or you need to use an execution context with non-daemon threads, for example:

implicit val ec: ExecutionContext =
  ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(8))

Hard to suggest specifics about thread pools without knowing the kind of work you're doing, but the bottom line is you need some regular non-daemon threads running so the JVM doesn't exit.