Reputation: 171
I'm using Java FileLock
to lock files in Clojure (on macOS). This is my code to acquire a lock:
(defn lock-file
[file-path]
(try
(let [file (io/file file-path)
channel (.getChannel (RandomAccessFile. file "rw"))]
(if-let [lock (.tryLock channel)]
channel
(do
(println (format "Lock on %s couldn't be acquired" file-path))
(System/exit 1))))
(catch OverlappingFileLockException _
(println (format "Lock on %s couldn't be acquired" file-path))
(System/exit 1))))
This works when both the processes are using lock-file
.
But a process can write to a file using spit
even if the file is locked by some other process. Does FileLock
not protect against that?
I'm failing to understand what is the use of FileLock
if it can't prevent this.
I want to get a read-write lock on a file. Any other process should not be able to read/write the locked file. Is there an idiomatic Clojure way of doing this?
Upvotes: 1
Views: 147
Reputation: 92067
If you want to coordinate things across processes, you need the operating system's help, of course: there's nothing you could do to affect another process without involving the OS. So, figure out what operating system you want to run this on, and look up if and how it manages file locks. On Linux, for example, all file locks are advisory. You can say, "hey, I'm using this file, and you probably shouldn't". But if another process ignores this advice, it can still use the file. See Obtain exclusive read/write lock on a file for atomic updates for some further discussion on this. Likewise the Javadoc for FileLock talks about how the behavior of file locks varies across operating systems.
Upvotes: 2