ExZarr.ArrayServer (ExZarr v1.1.0)
View SourceGenServer for coordinating concurrent access to Zarr arrays.
Provides chunk-level locking to prevent write conflicts while allowing concurrent reads. Monitors processes holding locks and automatically cleans up on process crashes.
Features
- Chunk-level read/write locks
- Multiple concurrent readers
- Exclusive writers
- Automatic lock cleanup on process crash
- Deadlock prevention via timeouts
- Process monitoring
Lock Semantics
- Read locks: Multiple processes can hold read locks on the same chunk simultaneously
- Write locks: Only one process can hold a write lock on a chunk at a time
- A chunk with a write lock cannot have any read locks (and vice versa)
- Locks are automatically released when the process terminates
Usage
# Start server for an array
{:ok, pid} = ExZarr.ArrayServer.start_link(array_id: "my_array")
# Acquire write lock on chunk {0, 0}
:ok = ExZarr.ArrayServer.lock_chunk(pid, {0, 0}, :write)
# Do write operation...
# Release lock
:ok = ExZarr.ArrayServer.unlock_chunk(pid, {0, 0})
# Acquire read lock (multiple processes can do this)
:ok = ExZarr.ArrayServer.lock_chunk(pid, {0, 0}, :read)
Summary
Functions
Returns a specification to start this module under a supervisor.
Returns information about all current locks.
Acquires a lock on a specific chunk.
Releases all locks held by the calling process.
Starts the ArrayServer for coordinating access to an array.
Attempts to acquire a lock without blocking.
Releases a lock on a chunk.
Types
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec get_locks(GenServer.server()) :: map()
Returns information about all current locks.
Useful for debugging and monitoring.
@spec lock_chunk(GenServer.server(), chunk_index(), lock_type(), lock_timeout()) :: :ok | {:error, term()}
Acquires a lock on a specific chunk.
Parameters
server- The ArrayServer processchunk_index- Tuple identifying the chunk (e.g.,{0, 0})lock_type- Either:reador:writetimeout- Maximum time to wait for lock (default: 5000ms)
Returns
:okif lock acquired{:error, :timeout}if lock couldn't be acquired within timeout{:error, reason}for other errors
@spec release_all_locks(GenServer.server()) :: :ok
Releases all locks held by the calling process.
Useful for cleanup in error scenarios.
@spec start_link(keyword()) :: GenServer.on_start()
Starts the ArrayServer for coordinating access to an array.
Options
:array_id- Unique identifier for the array (required):name- Process name (optional)
@spec try_lock_chunk(GenServer.server(), chunk_index(), lock_type()) :: :ok | {:error, :locked | term()}
Attempts to acquire a lock without blocking.
Returns immediately with :ok if lock acquired or {:error, :locked} if not available.
@spec unlock_chunk(GenServer.server(), chunk_index()) :: :ok | {:error, term()}
Releases a lock on a chunk.
The calling process must currently hold a lock on the chunk.