diff --git a/app/models/family.rb b/app/models/family.rb index ed919b11..3e877dc1 100644 --- a/app/models/family.rb +++ b/app/models/family.rb @@ -96,15 +96,15 @@ class Family < ApplicationRecord broadcast_refresh end - # If family has any syncs pending/syncing within the last hour, we show a persistent "syncing" notice. - # Ignore syncs older than 1 hour as they are considered "stale" + # If family has any syncs pending/syncing within the last 10 minutes, we show a persistent "syncing" notice. + # Ignore syncs older than 10 minutes as they are considered "stale" def syncing? Sync.where( "(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 = 'PlaidItem' AND syncable_id IN (SELECT id FROM plaid_items WHERE family_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 def eu? diff --git a/app/models/sync.rb b/app/models/sync.rb index 201fed02..da7b1a5c 100644 --- a/app/models/sync.rb +++ b/app/models/sync.rb @@ -41,10 +41,12 @@ class Sync < ApplicationRecord end def handle_child_completion_event - unless has_pending_child_syncs? - if has_failed_child_syncs? - fail!(Error.new("One or more child syncs failed")) - else + Sync.transaction do + # We need this to ensure 2 child syncs don't update the parent at the exact same time with different results + # and cause the sync to hang in "syncing" status indefinitely + self.lock! + + unless has_pending_child_syncs? complete! syncable.post_sync(self) end @@ -56,10 +58,6 @@ class Sync < ApplicationRecord children.where(status: [ :pending, :syncing ]).any? end - def has_failed_child_syncs? - children.where(status: :failed).any? - end - def has_parent? parent_id.present? end