Improve atomicWrite

We fsync the temp file before doing the atomic move, which I think is
necessary if the underlying filesystem re-orders the operations (e.g. if
the atomic move is performed before the writes to the temp file have
been flushed to disk).

Similarly we fsync the parent dir before returning. For a single atomic
write in isolation this probably isn't important, but probably is useful
if a sequence of atomic writes is performed in order.

Signed-off-by: Graham <gpe@openrs2.org>
Graham 3 years ago
parent 2292b9449c
commit f7e194dfa6
  1. 2
      util/src/main/kotlin/org/openrs2/util/io/PathExtensions.kt

@ -109,7 +109,9 @@ public inline fun <T> Path.useTempFile(
public inline fun <T> Path.atomicWrite(f: (Path) -> T): T { public inline fun <T> Path.atomicWrite(f: (Path) -> T): T {
parent.useTempFile(".$fileName", ".tmp") { tempFile -> parent.useTempFile(".$fileName", ".tmp") { tempFile ->
val result = f(tempFile) val result = f(tempFile)
tempFile.fsync()
Files.move(tempFile, this, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING) Files.move(tempFile, this, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
parent.fsync()
return result return result
} }
} }

Loading…
Cancel
Save