Windows Safe fsync in Java

Java fsync Directory の続き。

FileChannel.force は API としてぶっ壊れており、Windows ではディレクトリに対して force を呼ぶと例外が投げられるため(厳密に言えば、この挙動は implementation defined と明記されているが、とはいえ厳しくないか…)、UNIX 系 OS とは実装を分ける必要があります。

例えば以下のような実装にできます。IOUtil.fsync の内部が atomic な処理になっていないのでこれはこれで終わっています。しかし、solr の実装も確認しましたが概ねこのようになっているため、Java で atomic にするのは不可能ではないかと思います。代替案をご存知の方がいれば教えてください。

object IOUtil {
  def fsync(path: Path): Unit = {
    if (Files.exists(path)) {
      if (Files.isDirectory(path))
        fsyncDirectory(path)
      else
        doFsync(path)
    } else {
      // do nothing
    }
  }

  private def fsyncDirectory(path: Path): Unit = {
    if (Platform.isWindows)
      () // do nothing
    else
      doFsync(path)
  }

  private def doFsync(path: Path): Unit = {
    var channel: FileChannel = null

    try {
      channel = FileChannel.open(path, StandardOpenOption.READ)
      channel.force(true)
    } finally {
      if (channel != null) channel.close()
    }
  }
}

Comments

comments powered by Disqus