Add concurrency protection for Fava/Beancount ledger writes #5
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/concurrency-protection"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
This PR addresses critical race conditions when multiple requests try to write to the Fava/Beancount ledger file simultaneously. Without these protections, concurrent writes can cause data loss, duplicate entries, or file corruption.
Fixes #4
Fix Implemented
The following concurrency protections have been implemented:
1. Global Write Lock in FavaClient
Added
asyncio.Lock()to serialize all write operations to the Fava/Beancount ledger:2. Protected Write Methods
The following methods now acquire the global write lock before modifying the ledger:
add_entry()- Wrapped withasync with self._write_lock:add_account()- Wrapped with lock + retry logic for checksum conflictsupdate_entry_source()- Wrapped with lockdelete_entry()- Wrapped with lock3. Retry Logic with Exponential Backoff
add_account()now implements optimistic concurrency control:ChecksumConflictErrorif all retries fail4. Idempotent Entry Creation
New
add_entry_idempotent()method:5. Per-User Locking
Added
get_user_lock(user_id)method for user-specific operations:6. Protected Invoice Payment Processing
Updated
on_invoice_paid()in tasks.py:add_entry_idempotent()with payment hash as idempotency keyFiles Changed
fava_client.py- Added locks, retry logic, idempotent methodtasks.py- Updatedon_invoice_paid()to use new protectionsWhat This Fixes
Test Plan
Limitations
🤖 Generated with Claude Code
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.