FileLock (fnord v0.9.29)

View Source

Cross-process filesystem lock helpers for arbitrary files. Uses a lock dir with atomic stale lock takeover.

API is intentionally small:

  • acquire_lock(path)
  • release_lock(path)
  • with_lock(path, fun, opts \ [])

Summary

Functions

Acquire a lock directory alongside the file at path.

Returns a map describing the current holder of the lock at path, or nil if no lock exists. Useful when reporting lock contention to the user.

Release the lock directory created for path.

Return the bounded retry delay used between lock acquisition attempts.

Execute fun while holding a lock for path.

Functions

acquire_lock(path)

@spec acquire_lock(path :: binary()) :: :ok | {:error, term()}

Acquire a lock directory alongside the file at path.

Returns :ok on success, {:error, reason} on failure.

read_owner_info(path)

@spec read_owner_info(path :: binary()) :: map() | nil

Returns a map describing the current holder of the lock at path, or nil if no lock exists. Useful when reporting lock contention to the user.

Keys: "os_pid", "beam_pid", "at" - exactly the fields written by write_owner_info/1, parsed as a flat string map. May be empty if the owner file is missing or malformed (e.g. the directory exists but the owner file was never written, or was written in an older format).

release_lock(path)

@spec release_lock(path :: binary()) :: :ok

Release the lock directory created for path.

retry_delay_ms_for_test(attempt)

@spec retry_delay_ms_for_test(non_neg_integer()) :: non_neg_integer()

Return the bounded retry delay used between lock acquisition attempts.

This supports the contention policy exercised by the integration tests.

with_lock(path, fun, opts \\ [])

@spec with_lock(binary(), (-> any()), keyword()) ::
  {:ok, any()}
  | {:error, :lock_failed}
  | {:error, term()}
  | {:callback_error, Exception.t()}

Execute fun while holding a lock for path.

Returns:

  • {:ok, result} when the callback returns normally
  • {:error, :lock_failed} when the lock cannot be acquired
  • {:callback_error, exception} when the callback raises
  • any {:error, reason} tuple returned by the callback itself