Skip to content

Commit fa98bc8

Browse files
Merge branch 'main' into patch-1 + fix merge conflict
# Conflicts: # Apollo.xcodeproj/project.pbxproj
2 parents 16dd2c7 + f4c0583 commit fa98bc8

44 files changed

Lines changed: 3934 additions & 2057 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ version: 2.1
33
parameters:
44
xcode_version:
55
type: string
6-
default: "12.0.0"
6+
default: "12.1.0"
77
ios_current_version:
88
type: string
9-
default: "14.0"
9+
default: "14.1"
1010
ios_previous_version:
1111
type: string
1212
default: "13.5"
1313
ios_sdk:
1414
type: string
15-
default: "iphonesimulator14.0"
15+
default: "iphonesimulator14.1"
1616
macos_version: # The user-facing version string for macOS builds
1717
type: string
1818
default: "10.15"
@@ -63,13 +63,33 @@ commands:
6363
command: xcodebuild clean build build-for-testing -project "Apollo.xcodeproj" -scheme "${CIRCLE_XCODE_SCHEME}" -sdk "${CIRCLE_XCODE_SDK}" -destination "${DESTINATION}" | xcpretty
6464
name: Clean and build for testing
6565
- run:
66-
command: xcodebuild test-without-building -project "Apollo.xcodeproj" -scheme "${CIRCLE_XCODE_SCHEME}" -sdk "${CIRCLE_XCODE_SDK}" -destination "${DESTINATION}" | xcpretty
66+
command: xcodebuild test-without-building -resultBundlePath ~/TestResults/ResultBundle.xcresult -project "Apollo.xcodeproj" -scheme "${CIRCLE_XCODE_SCHEME}" -sdk "${CIRCLE_XCODE_SDK}" -destination "${DESTINATION}" | xcpretty
6767
name: Run tests
68+
- save-xcodebuild-artifacts
6869
- save_cache:
6970
key: starwars-server
7071
paths:
7172
- ../starwars-server
72-
73+
save-xcodebuild-artifacts:
74+
description: Save artifacts logs, crash reports and test results generated by xcodebuild
75+
steps:
76+
- store_artifacts:
77+
name: Save xcodebuild logs
78+
path: logs
79+
destination: logs
80+
- store_artifacts:
81+
name: Save crash logs
82+
path: ~/Library/Logs/DiagnosticReports/
83+
destination: crashes
84+
- run:
85+
name: Zip result bundle
86+
working_directory: ~/TestResults
87+
command: zip -r ResultBundle.zip ResultBundle.xcresult
88+
when: always
89+
- store_artifacts:
90+
name: Save test results
91+
path: ~/TestResults/ResultBundle.zip
92+
destination: results
7393

7494
# Important! When adding a new job to `jobs`, make sure to define when it
7595
# executes by also adding it to the `workflows` section below!

Apollo.xcodeproj/project.pbxproj

Lines changed: 173 additions & 6 deletions
Large diffs are not rendered by default.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1210"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
</BuildAction>
9+
<TestAction
10+
buildConfiguration = "PerformanceTesting"
11+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
12+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
13+
shouldUseLaunchSchemeArgsEnv = "YES"
14+
disableMainThreadChecker = "YES">
15+
<Testables>
16+
<TestableReference
17+
skipped = "NO">
18+
<BuildableReference
19+
BuildableIdentifier = "primary"
20+
BlueprintIdentifier = "9F54C8B3255D760B0065AFD6"
21+
BuildableName = "ApolloPerformanceTests.xctest"
22+
BlueprintName = "ApolloPerformanceTests"
23+
ReferencedContainer = "container:Apollo.xcodeproj">
24+
</BuildableReference>
25+
</TestableReference>
26+
</Testables>
27+
</TestAction>
28+
<LaunchAction
29+
buildConfiguration = "Debug"
30+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
31+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
32+
launchStyle = "0"
33+
useCustomWorkingDirectory = "NO"
34+
ignoresPersistentStateOnLaunch = "NO"
35+
debugDocumentVersioning = "YES"
36+
debugServiceExtension = "internal"
37+
allowLocationSimulation = "YES">
38+
</LaunchAction>
39+
<ProfileAction
40+
buildConfiguration = "Release"
41+
shouldUseLaunchSchemeArgsEnv = "YES"
42+
savedToolIdentifier = ""
43+
useCustomWorkingDirectory = "NO"
44+
debugDocumentVersioning = "YES">
45+
</ProfileAction>
46+
<AnalyzeAction
47+
buildConfiguration = "Debug">
48+
</AnalyzeAction>
49+
<ArchiveAction
50+
buildConfiguration = "Release"
51+
revealArchiveInOrganizer = "YES">
52+
</ArchiveAction>
53+
</Scheme>

Apollo.xcodeproj/xcuserdata/martijnwalraven.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 0 additions & 129 deletions
This file was deleted.

Configuration/Apollo/Apollo-Project-Performance-Testing.xcconfig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,3 @@
33
COPY_PHASE_STRIP = NO
44
ENABLE_BITCODE = NO
55
ENABLE_TESTABILITY = YES
6-
TEST_HOST = $(BUILT_PRODUCTS_DIR)/TestHost iOS.app/TestHost iOS
7-
8-
CODE_SIGN_IDENTITY = iPhone Developer;
9-
CODE_SIGN_STYLE = Automatic;

Sources/Apollo/ApolloStore.swift

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)