Skip to content

Commit

Permalink
Merge pull request #763 from apollographql/read-transaction-deadlock
Browse files Browse the repository at this point in the history
Read transaction deadlock + fix SQLite checkout
  • Loading branch information
designatednerd authored Sep 16, 2019
2 parents c99e37e + d860874 commit bd6f03e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Sources/Apollo/DataLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ final class DataLoader<Key: Hashable, Value> {

let keys = loads.map { $0.key }

self.batchLoad(keys).andThen { values in
self.batchLoad(keys).catch { error in
loads.forEach { $0.reject(error) }
}.andThen { values in
for (load, value) in zip(loads, values) {
load.fulfill(value)
}
Expand Down
61 changes: 61 additions & 0 deletions Tests/ApolloCacheDependentTests/LoadQueryFromStoreTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import XCTest
@testable import Apollo
#if canImport(ApolloSQLite)
import ApolloSQLite
#endif
import ApolloTestSupport
import StarWarsAPI

Expand Down Expand Up @@ -259,6 +262,64 @@ class LoadQueryFromStoreTests: XCTestCase {
}
}


func testLoadingWithBadCacheSerialization() throws {
let initialRecords: RecordSet = [
"QUERY_ROOT": ["hero": Reference(key: "2001")],
"2001": [
"name": "R2-D2",
"__typename": "Droid",
"friends": [
Reference(key: "1000"),
Reference(key: "1002"),
Reference(key: "1003")
]
],
"1000": ["__typename": "Human", "name": ["dictionary": "badValues", "nested bad val": ["subdictionary": "some value"] ]
],
"1002": ["__typename": "Human", "name": "Han Solo"],
"1003": ["__typename": "Human", "name": "Leia Organa"],
]

withCache(initialRecords: initialRecords) { (cache) in
store = ApolloStore(cache: cache)

let query = HeroAndFriendsNamesQuery()
load(query: query) { result in
switch result {
case .success:
XCTFail("Should not have succeeded!")
case .failure(let error):
guard let graphQLError = error as? GraphQLResultError else {
XCTFail("Incorrect error type for primary error: \(error)")
return
}

switch graphQLError.underlying {
case is JSONDecodingError:
if (cache is InMemoryNormalizedCache) {
// This is expected for in-memory caching
break
} else {
XCTFail("Incorrect error type for underlying with in-memory cache: \(graphQLError.underlying)")
}
#if canImport(ApolloSQLite)
case is SQLiteNormalizedCacheError:
if (cache is SQLiteNormalizedCache) {
// This is expected for SQLite caching
break
} else {
XCTFail("Incorrect error type for underlying with SQLite cache: \(graphQLError.underlying)")
}
#endif
default:
XCTFail("Incorrect error type for underlying: \(graphQLError.underlying)")
}
}
}
}
}

// MARK: - Helpers

private func load<Query: GraphQLQuery>(query: Query, resultHandler: @escaping GraphQLResultHandler<Query.Data>) {
Expand Down

0 comments on commit bd6f03e

Please sign in to comment.