From 0aac00756a9a30a3b8a7ebf9e4e8432edc9936cf Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Fri, 29 Jan 2016 00:31:58 -0800 Subject: [PATCH] fix(query): Invalidate in-flight updates when query changes --- .../models/mutable-query-subscription.coffee | 2 ++ src/flux/models/query-subscription.coffee | 36 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/flux/models/mutable-query-subscription.coffee b/src/flux/models/mutable-query-subscription.coffee index b96afa230..072c5f6e5 100644 --- a/src/flux/models/mutable-query-subscription.coffee +++ b/src/flux/models/mutable-query-subscription.coffee @@ -9,6 +9,8 @@ class MutableQuerySubscription extends QuerySubscription rangeIsOnlyChange = @_query?.clone().offset(0).limit(0).sql() is nextQuery.clone().offset(0).limit(0).sql() + @cancelPendingUpdate() + nextQuery.finalize() @_query = nextQuery @_set = null unless @_set and rangeIsOnlyChange diff --git a/src/flux/models/query-subscription.coffee b/src/flux/models/query-subscription.coffee index 585d66c6f..1416781d4 100644 --- a/src/flux/models/query-subscription.coffee +++ b/src/flux/models/query-subscription.coffee @@ -3,8 +3,6 @@ DatabaseStore = require '../stores/database-store' QueryRange = require './query-range' MutableQueryResultSet = require './mutable-query-result-set' -verbose = false - class QuerySubscription constructor: (@_query, @_options = {}) -> @_set = null @@ -12,6 +10,7 @@ class QuerySubscription @_lastResult = null @_updateInFlight = false @_queuedChangeRecords = [] + @_queryVersion = 1 if @_query if @_query._count @@ -111,9 +110,7 @@ class QuerySubscription @_queuedChangeRecords = [] if unknownImpacts > 0 - if mustRefetchAllIds - @log("Clearing result set - mustRefetchAllIds") - @_set = null + @_set = null if mustRefetchAllIds @update() else if knownImpacts > 0 @_createResultAndTrigger() @@ -129,15 +126,13 @@ class QuerySubscription return false - log: (msg) => - return unless verbose - console.log(msg) if @_query._klass.name is 'Thread' - update: => desiredRange = @_query.range() currentRange = @_set?.range() @_updateInFlight = true + version = @_queryVersion + if currentRange and not currentRange.isInfinite() and not desiredRange.isInfinite() ranges = QueryRange.rangesBySubtracting(desiredRange, currentRange) entireModels = true @@ -146,16 +141,19 @@ class QuerySubscription entireModels = not @_set or @_set.modelCacheCount() is 0 Promise.each ranges, (range) => - @log("Update (#{@_query._klass.name}) - Fetching range #{range}") - @_fetchRange(range, {entireModels}) + return unless @_queryVersion is version + @_fetchRange(range, {entireModels, version}) + .then => + return unless @_queryVersion is version ids = @_set.ids().filter (id) => not @_set.modelWithId(id) - return @log("Update (#{@_query._klass.name}) - No missing Ids") if ids.length is 0 - @log("Update (#{@_query._klass.name}) - Fetching missing Ids: #{ids}") + return if ids.length is 0 return DatabaseStore.findAll(@_query._klass, {id: ids}).then (models) => - @log("Update (#{@_query._klass.name}) - Fetched missing Ids") + return unless @_queryVersion is version @_set.replaceModel(m) for m in models + .then => + return unless @_queryVersion is version @_updateInFlight = false allChangesApplied = @_queuedChangeRecords.length is 0 @@ -169,12 +167,15 @@ class QuerySubscription throw new Error("QuerySubscription: Applied all changes and result set is missing models.") if allChangesApplied and allCompleteModels and allUniqueIds - @log("Update (#{@_query._klass.name}) - Triggering...") @_createResultAndTrigger() else @_processChangeRecords() - _fetchRange: (range, {entireModels} = {}) -> + cancelPendingUpdate: => + @_queryVersion += 1 + @_updateInFlight = false + + _fetchRange: (range, {entireModels, version} = {}) -> rangeQuery = undefined unless range.isInfinite() @@ -188,8 +189,9 @@ class QuerySubscription rangeQuery ?= @_query DatabaseStore.run(rangeQuery, {format: false}).then (results) => + return unless @_queryVersion is version + if @_set and not @_set.range().isContiguousWith(range) - @log("Clearing result set - #{range} isnt contiguous with #{@_set.range()}") @_set = null @_set ?= new MutableQueryResultSet()