Transactions
Committing a single or batch of changes, with preconditions and idempotency keys for safe retries.
Understanding transactions in LoonFS
Section titled “Understanding transactions in LoonFS”LoonFS supports transactional commits within each namespace. The atomic unit of a transaction is called a “commit”.
A commit request contains a client-generated commit_id, an optional message, optional preconditions, and an ordered list of operations that commit all together or not at all. Remember to include the required Loonfs-Actor header with the actor ID. Commits are acknowledged only once durable; see Write-ahead log.
Filesystem operations
Section titled “Filesystem operations”kind | Fields (* required) |
|---|---|
create_directory | *path, parents |
create_directory_by_inode | *parent_inode_id, *display_name |
put_file | *path, content, behavior, expected_inode_id, expected_revision_no |
create_file_by_inode | *parent_inode_id, *display_name, content |
put_file_revision_by_inode | *inode_id, content, *expected_revision_no |
delete_path | *path, behavior, expected_inode_id |
delete_by_inode | *inode_id, *expected_binding_version, behavior |
move_path | *source_path, *destination_path, behavior, expected_destination_inode_id, expected_destination_revision_no |
move_by_inode | *inode_id, *expected_binding_version, *destination_parent_inode_id, *destination_display_name, behavior, expected_destination_inode_id, expected_destination_revision_no |
copy_path | *source_path, *destination_path, behavior, expected_destination_inode_id, expected_destination_revision_no |
undelete | *inode_id, *deletion_seq, destination_path |
restore_revision | *path, *source_revision_no |
update_attributes | *path, set, remove, expected_inode_id, expected_attributes_revision_no |
update_access | *path, *boundary, *grants, expected_inode_id, expected_access_revision_no |
For each content-writing operation, supply exactly one of content_ref (with its proof in the request’s content_tokens) or base64 inline_content. Inline writes require filesystem.commits.inline_content and must fit commit.max_inline_content_bytes_per_operation per file. See Uploads & downloads.
The commit response includes committed_seq, committed_by (the actor ID), committed_at_ms, and the commit’s events. Retries may omit events if the WAL entry has been removed.
Read more about the commit API here: Apply a commit.
Anticipating possible conflicts
Section titled “Anticipating possible conflicts”LoonFS supports preconditions and uses optimistic concurrency control. This means clients may supply optional preconditions on commits so that a write only lands if the namespace still matches the state the client expects.
Depending on the operation, these preconditions include expected_revision_no, expected_inode_id, expected_attributes_revision_no, expected_access_revision_no, expected_binding_version, and the deletion_seq used for recovery. If you set expected_revision_no on put_file, include expected_inode_id too.
The request-level preconditions array checks the state before any operations run. Its kinds are namespace_head, file_revision, path_binding, path_absence, attributes_revision, and access_revision.
If a precondition fails, the whole commit is rejected. To see what failed, check details.precondition_index in the error response. For example, a value of 0 means the first item in your preconditions list failed.
This means that genuine conflicts can be handled elegantly by the client depending on the preferred behavior. For example, if two clients are racing to replace the same file content, only one transaction will commit when both supply the same expected_revision_no. The losing client can reload the current revision and decide whether to retry with a new precondition, merge the changes, or write the result to a different path.
Every named path entry carries an opaque binding_version. Supply the value last read when using move_by_inode or delete_by_inode; if that inode has been moved, deleted, or rebound, the commit fails with binding_version_mismatch instead of assuming a stale location state.
Committing with idempotency
Section titled “Committing with idempotency”Every HTTP commit requires a commit_id for idempotency. Retry with the same ID, body, actor, and subject after a timeout or uncertain outcome. While its receipt is retained, an identical request returns the original result; changing the request returns commit_id_reuse_conflict. Once the receipt is deleted, a retry can apply the operation again.