@@ -101,7 +101,7 @@ public final class ApolloStore {
101101 self . queue. async {
102102 self . cacheLock. lockForReading ( )
103103
104- fulfill ( ReadTransaction ( cache : self . cache , cacheKeyForObject : self . cacheKeyForObject ) )
104+ fulfill ( ReadTransaction ( store : self ) )
105105 }
106106 } . flatMap ( body)
107107 . finally {
@@ -137,9 +137,7 @@ public final class ApolloStore {
137137 return Promise< ReadWriteTransaction> { fulfill, reject in
138138 self . queue. async ( flags: . barrier) {
139139 self . cacheLock. lockForWriting ( )
140- fulfill ( ReadWriteTransaction ( cache: self . cache,
141- cacheKeyForObject: self . cacheKeyForObject,
142- updateChangedKeysFunc: self . didChangeKeys) )
140+ fulfill ( ReadWriteTransaction ( store: self ) )
143141 }
144142 } . flatMap ( body)
145143 . finally {
@@ -203,14 +201,16 @@ public final class ApolloStore {
203201 }
204202
205203 public class ReadTransaction {
204+ fileprivate let queue : DispatchQueue
206205 fileprivate let cache : NormalizedCache
207206 fileprivate let cacheKeyForObject : CacheKeyForObject ?
208207
209208 fileprivate lazy var loader : DataLoader < CacheKey , Record ? > = DataLoader ( self . cache. loadRecordsPromise)
210209
211- init ( cache: NormalizedCache , cacheKeyForObject: CacheKeyForObject ? ) {
212- self . cache = cache
213- self . cacheKeyForObject = cacheKeyForObject
210+ fileprivate init ( store: ApolloStore ) {
211+ self . queue = DispatchQueue ( label: " com.apollographql.ApolloStore. \( type ( of: self ) ) " )
212+ self . cache = store. cache
213+ self . cacheKeyForObject = store. cacheKeyForObject
214214 }
215215
216216 public func read< Query: GraphQLQuery > ( query: Query ) throws -> Query . Data {
@@ -242,17 +242,15 @@ public final class ApolloStore {
242242 return . promise( loader [ reference. key] . map { $0? . fields } )
243243 } else if let array = value as? Array < Any ? > {
244244 let completedValues = array. map ( complete)
245- // Make sure to dispatch on a global queue and not on the local queue,
246- // because that could result in a deadlock (if someone is waiting for the write lock).
247- return whenAll ( completedValues, notifyOn: . global( ) ) . map { $0 }
245+ return whenAll ( completedValues, notifyOn: queue) . map { $0 }
248246 } else {
249247 return . result( . success( value) )
250248 }
251249 }
252250
253- final func execute< Accumulator: GraphQLResultAccumulator > ( selections: [ GraphQLSelection ] , onObjectWithKey key: CacheKey , variables: GraphQLMap ? , accumulator: Accumulator ) throws -> Promise < Accumulator . FinalResult > {
254- return loadObject ( forKey: key) . flatMap { object in
255- let executor = GraphQLExecutor { object, info in
251+ fileprivate func execute< Accumulator: GraphQLResultAccumulator > ( selections: [ GraphQLSelection ] , onObjectWithKey key: CacheKey , variables: GraphQLMap ? , accumulator: Accumulator ) throws -> Promise < Accumulator . FinalResult > {
252+ return loadObject ( forKey: key) . flatMap { [ queue ] object in
253+ let executor = GraphQLExecutor ( queue : queue ) { object, info in
256254 let value = object [ info. cacheKeyForField]
257255 return self . complete ( value: value)
258256 }
@@ -282,9 +280,9 @@ public final class ApolloStore {
282280
283281 fileprivate var updateChangedKeysFunc : DidChangeKeysFunc ?
284282
285- init ( cache : NormalizedCache , cacheKeyForObject : CacheKeyForObject ? , updateChangedKeysFunc : @escaping DidChangeKeysFunc ) {
286- self . updateChangedKeysFunc = updateChangedKeysFunc
287- super. init ( cache : cache , cacheKeyForObject : cacheKeyForObject )
283+ override init ( store : ApolloStore ) {
284+ self . updateChangedKeysFunc = store . didChangeKeys
285+ super. init ( store : store )
288286 }
289287
290288 public func update< Query: GraphQLQuery > ( query: Query , _ body: ( inout Query . Data ) throws -> Void ) throws {
@@ -323,7 +321,7 @@ public final class ApolloStore {
323321 withKey key: CacheKey ,
324322 variables: GraphQLMap ? ) throws {
325323 let normalizer = GraphQLResultNormalizer ( )
326- let executor = GraphQLExecutor { object, info in
324+ let executor = GraphQLExecutor ( queue : queue ) { object, info in
327325 return . result( . success( object [ info. responseKeyForField] ) )
328326 }
329327
@@ -337,6 +335,10 @@ public final class ApolloStore {
337335 . flatMap {
338336 self . cache. mergePromise ( records: $0)
339337 } . andThen { changedKeys in
338+ // Remove cached values from the data loader, so subsequent reads
339+ // within the same transaction will reload the updated value.
340+ self . loader. removeAll ( )
341+
340342 if let didChangeKeysFunc = self . updateChangedKeysFunc {
341343 didChangeKeysFunc ( changedKeys, nil )
342344 }
0 commit comments