Suvrat Apte
Suvrat Apte

Reputation: 171

File locking in Clojure

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

Answers (1)

amalloy
amalloy

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

Related Questions