1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-20 13:49:39 +02:00

Transactional locks for sync completions (#2219)

* Transactional locks for sync completions

* Lower sync display logic tolerance in UI
This commit is contained in:
Zach Gollwitzer 2025-05-07 16:28:58 -04:00 committed by GitHub
parent 71be2a04ad
commit a07e9d40a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 9 additions and 11 deletions

View file

@ -96,15 +96,15 @@ class Family < ApplicationRecord
broadcast_refresh broadcast_refresh
end end
# If family has any syncs pending/syncing within the last hour, we show a persistent "syncing" notice. # If family has any syncs pending/syncing within the last 10 minutes, we show a persistent "syncing" notice.
# Ignore syncs older than 1 hour as they are considered "stale" # Ignore syncs older than 10 minutes as they are considered "stale"
def syncing? def syncing?
Sync.where( Sync.where(
"(syncable_type = 'Family' AND syncable_id = ?) OR "(syncable_type = 'Family' AND syncable_id = ?) OR
(syncable_type = 'Account' AND syncable_id IN (SELECT id FROM accounts WHERE family_id = ? AND plaid_account_id IS NULL)) OR (syncable_type = 'Account' AND syncable_id IN (SELECT id FROM accounts WHERE family_id = ? AND plaid_account_id IS NULL)) OR
(syncable_type = 'PlaidItem' AND syncable_id IN (SELECT id FROM plaid_items WHERE family_id = ?))", (syncable_type = 'PlaidItem' AND syncable_id IN (SELECT id FROM plaid_items WHERE family_id = ?))",
id, id, id id, id, id
).where(status: [ "pending", "syncing" ], created_at: 1.hour.ago..).exists? ).where(status: [ "pending", "syncing" ], created_at: 10.minutes.ago..).exists?
end end
def eu? def eu?

View file

@ -41,10 +41,12 @@ class Sync < ApplicationRecord
end end
def handle_child_completion_event def handle_child_completion_event
unless has_pending_child_syncs? Sync.transaction do
if has_failed_child_syncs? # We need this to ensure 2 child syncs don't update the parent at the exact same time with different results
fail!(Error.new("One or more child syncs failed")) # and cause the sync to hang in "syncing" status indefinitely
else self.lock!
unless has_pending_child_syncs?
complete! complete!
syncable.post_sync(self) syncable.post_sync(self)
end end
@ -56,10 +58,6 @@ class Sync < ApplicationRecord
children.where(status: [ :pending, :syncing ]).any? children.where(status: [ :pending, :syncing ]).any?
end end
def has_failed_child_syncs?
children.where(status: :failed).any?
end
def has_parent? def has_parent?
parent_id.present? parent_id.present?
end end