Skip to content

Commit 39cc853

Browse files
committed
Add sync resolve.
1 parent 43ea113 commit 39cc853

File tree

17 files changed

+441
-332
lines changed

17 files changed

+441
-332
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1100"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "GraphQL"
18+
BuildableName = "GraphQL"
19+
BlueprintName = "GraphQL"
20+
ReferencedContainer = "container:">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
<BuildActionEntry
24+
buildForTesting = "YES"
25+
buildForRunning = "YES"
26+
buildForProfiling = "YES"
27+
buildForArchiving = "YES"
28+
buildForAnalyzing = "YES">
29+
<BuildableReference
30+
BuildableIdentifier = "primary"
31+
BlueprintIdentifier = "GraphQLTests"
32+
BuildableName = "GraphQLTests"
33+
BlueprintName = "GraphQLTests"
34+
ReferencedContainer = "container:">
35+
</BuildableReference>
36+
</BuildActionEntry>
37+
</BuildActionEntries>
38+
</BuildAction>
39+
<TestAction
40+
buildConfiguration = "Debug"
41+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43+
shouldUseLaunchSchemeArgsEnv = "YES">
44+
<Testables>
45+
<TestableReference
46+
skipped = "NO">
47+
<BuildableReference
48+
BuildableIdentifier = "primary"
49+
BlueprintIdentifier = "GraphQLTests"
50+
BuildableName = "GraphQLTests"
51+
BlueprintName = "GraphQLTests"
52+
ReferencedContainer = "container:">
53+
</BuildableReference>
54+
</TestableReference>
55+
</Testables>
56+
</TestAction>
57+
<LaunchAction
58+
buildConfiguration = "Debug"
59+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
60+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
61+
launchStyle = "0"
62+
useCustomWorkingDirectory = "NO"
63+
ignoresPersistentStateOnLaunch = "NO"
64+
debugDocumentVersioning = "YES"
65+
debugServiceExtension = "internal"
66+
allowLocationSimulation = "YES">
67+
</LaunchAction>
68+
<ProfileAction
69+
buildConfiguration = "Release"
70+
shouldUseLaunchSchemeArgsEnv = "YES"
71+
savedToolIdentifier = ""
72+
useCustomWorkingDirectory = "NO"
73+
debugDocumentVersioning = "YES">
74+
<MacroExpansion>
75+
<BuildableReference
76+
BuildableIdentifier = "primary"
77+
BlueprintIdentifier = "GraphQL"
78+
BuildableName = "GraphQL"
79+
BlueprintName = "GraphQL"
80+
ReferencedContainer = "container:">
81+
</BuildableReference>
82+
</MacroExpansion>
83+
</ProfileAction>
84+
<AnalyzeAction
85+
buildConfiguration = "Debug">
86+
</AnalyzeAction>
87+
<ArchiveAction
88+
buildConfiguration = "Release"
89+
revealArchiveInOrganizer = "YES">
90+
</ArchiveAction>
91+
</Scheme>

Sources/GraphQL/Execution/Execute.swift

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public protocol FieldExecutionStrategy {
9999
sourceValue: Any,
100100
path: IndexPath,
101101
fields: [String: [Field]]
102-
) throws -> EventLoopFuture<[String: Any]>
102+
) throws -> Future<[String: Any]>
103103
}
104104

105105
public protocol MutationFieldExecutionStrategy: FieldExecutionStrategy {}
@@ -119,8 +119,8 @@ public struct SerialFieldExecutionStrategy: QueryFieldExecutionStrategy, Mutatio
119119
sourceValue: Any,
120120
path: IndexPath,
121121
fields: [String: [Field]]
122-
) throws -> EventLoopFuture<[String: Any]> {
123-
var results = [String: EventLoopFuture<Any>]()
122+
) throws -> Future<[String: Any]> {
123+
var results = [String: Future<Any>]()
124124

125125
try fields.forEach { field in
126126
let fieldASTs = field.value
@@ -154,7 +154,10 @@ public struct ConcurrentDispatchFieldExecutionStrategy: QueryFieldExecutionStrat
154154
self.dispatchQueue = dispatchQueue
155155
}
156156

157-
public init(queueLabel: String = "GraphQL field execution", queueQoS: DispatchQoS = .userInitiated) {
157+
public init(
158+
queueLabel: String = "GraphQL field execution",
159+
queueQoS: DispatchQoS = .userInitiated
160+
) {
158161
self.dispatchQueue = DispatchQueue(
159162
label: queueLabel,
160163
qos: queueQoS,
@@ -168,14 +171,14 @@ public struct ConcurrentDispatchFieldExecutionStrategy: QueryFieldExecutionStrat
168171
sourceValue: Any,
169172
path: IndexPath,
170173
fields: [String: [Field]]
171-
) throws -> EventLoopFuture<[String: Any]> {
172-
174+
) throws -> Future<[String: Any]> {
173175
let resultsQueue = DispatchQueue(
174176
label: "\(dispatchQueue.label) results",
175177
qos: dispatchQueue.qos
176178
)
179+
177180
let group = DispatchGroup()
178-
var results: [String: EventLoopFuture<Any>] = [:]
181+
var results: [String: Future<Any>] = [:]
179182
var err: Error? = nil
180183

181184
fields.forEach { field in
@@ -204,7 +207,9 @@ public struct ConcurrentDispatchFieldExecutionStrategy: QueryFieldExecutionStrat
204207
}
205208
}
206209
}
210+
207211
group.wait()
212+
208213
if let error = err {
209214
throw error
210215
}
@@ -232,7 +237,7 @@ func execute(
232237
eventLoopGroup: EventLoopGroup,
233238
variableValues: [String: Map] = [:],
234239
operationName: String? = nil
235-
) -> EventLoopFuture<GraphQLResult> {
240+
) -> Future<GraphQLResult> {
236241
let executeStarted = instrumentation.now
237242
let buildContext: ExecutionContext
238243

@@ -410,7 +415,7 @@ func executeOperation(
410415
exeContext: ExecutionContext,
411416
operation: OperationDefinition,
412417
rootValue: Any
413-
) throws -> EventLoopFuture<[String : Any]> {
418+
) throws -> Future<[String: Any]> {
414419
let type = try getOperationRootType(schema: exeContext.schema, operation: operation)
415420
var inputFields: [String : [Field]] = [:]
416421
var visitedFragmentNames: [String : Bool] = [:]
@@ -655,7 +660,7 @@ public func resolveField(
655660
source: Any,
656661
fieldASTs: [Field],
657662
path: IndexPath
658-
) throws -> EventLoopFuture<Any?> {
663+
) throws -> Future<Any?> {
659664
let fieldAST = fieldASTs[0]
660665
let fieldName = fieldAST.name.value
661666

@@ -697,7 +702,7 @@ public func resolveField(
697702
variableValues: exeContext.variableValues
698703
)
699704

700-
let resolveFieldStarted = exeContext.instrumentation.now
705+
// let resolveFieldStarted = exeContext.instrumentation.now
701706

702707
// Get the resolve func, regardless of if its result is normal
703708
// or abrupt (error).
@@ -710,17 +715,17 @@ public func resolveField(
710715
info: info
711716
)
712717

713-
exeContext.instrumentation.fieldResolution(
714-
processId: processId(),
715-
threadId: threadId(),
716-
started: resolveFieldStarted,
717-
finished: exeContext.instrumentation.now,
718-
source: source,
719-
args: args,
720-
eventLoopGroup: exeContext.eventLoopGroup,
721-
info: info,
722-
result: result
723-
)
718+
// exeContext.instrumentation.fieldResolution(
719+
// processId: processId(),
720+
// threadId: threadId(),
721+
// started: resolveFieldStarted,
722+
// finished: exeContext.instrumentation.now,
723+
// source: source,
724+
// args: args,
725+
// eventLoopGroup: exeContext.eventLoopGroup,
726+
// info: info,
727+
// result: result
728+
// )
724729

725730
return try completeValueCatchingError(
726731
exeContext: exeContext,
@@ -732,11 +737,6 @@ public func resolveField(
732737
)
733738
}
734739

735-
public enum ResultOrError<T, E> {
736-
case result(T)
737-
case error(E)
738-
}
739-
740740
// Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
741741
// function. Returns the result of `resolve` or the abrupt-return Error object.
742742
func resolveOrError(
@@ -746,11 +746,12 @@ func resolveOrError(
746746
context: Any,
747747
eventLoopGroup: EventLoopGroup,
748748
info: GraphQLResolveInfo
749-
) -> ResultOrError<EventLoopFuture<Any?>, Error> {
749+
) -> Result<Future<Any?>, Error> {
750750
do {
751-
return try .result(resolve(source, args, context, eventLoopGroup, info))
751+
let result = try resolve(source, args, context, eventLoopGroup, info)
752+
return .success(result)
752753
} catch {
753-
return .error(error)
754+
return .failure(error)
754755
}
755756
}
756757

@@ -762,8 +763,8 @@ func completeValueCatchingError(
762763
fieldASTs: [Field],
763764
info: GraphQLResolveInfo,
764765
path: IndexPath,
765-
result: ResultOrError<EventLoopFuture<Any?>, Error>
766-
) throws -> EventLoopFuture<Any?> {
766+
result: Result<Future<Any?>, Error>
767+
) throws -> Future<Any?> {
767768
// If the field type is non-nullable, then it is resolved without any
768769
// protection from errors, however it still properly locates the error.
769770
if let returnType = returnType as? GraphQLNonNull {
@@ -787,13 +788,13 @@ func completeValueCatchingError(
787788
info: info,
788789
path: path,
789790
result: result
790-
).mapIfError { error -> Any? in
791-
guard let error = error as? GraphQLError else {
792-
fatalError()
793-
}
794-
exeContext.append(error: error)
795-
return nil
791+
).mapIfError { error -> Any? in
792+
guard let error = error as? GraphQLError else {
793+
fatalError()
796794
}
795+
exeContext.append(error: error)
796+
return nil
797+
}
797798

798799
return completed
799800
} catch let error as GraphQLError {
@@ -814,8 +815,8 @@ func completeValueWithLocatedError(
814815
fieldASTs: [Field],
815816
info: GraphQLResolveInfo,
816817
path: IndexPath,
817-
result: ResultOrError<EventLoopFuture<Any?>, Error>
818-
) throws -> EventLoopFuture<Any?> {
818+
result: Result<Future<Any?>, Error>
819+
) throws -> Future<Any?> {
819820
do {
820821
let completed = try completeValue(
821822
exeContext: exeContext,
@@ -864,12 +865,12 @@ func completeValue(
864865
fieldASTs: [Field],
865866
info: GraphQLResolveInfo,
866867
path: IndexPath,
867-
result: ResultOrError<EventLoopFuture<Any?>, Error>
868-
) throws -> EventLoopFuture<Any?> {
868+
result: Result<Future<Any?>, Error>
869+
) throws -> Future<Any?> {
869870
switch result {
870-
case .error(let error):
871+
case let .failure(error):
871872
throw error
872-
case .result(let result):
873+
case let .success(result):
873874
// If field type is NonNull, complete for inner type, and throw field error
874875
// if result is nullish.
875876
if let returnType = returnType as? GraphQLNonNull {
@@ -879,7 +880,7 @@ func completeValue(
879880
fieldASTs: fieldASTs,
880881
info: info,
881882
path: path,
882-
result: .result(result)
883+
result: .success(result)
883884
).thenThrowing { value -> Any? in
884885
guard let value = value else {
885886
throw GraphQLError(message: "Cannot return null for non-nullable field \(info.parentType.name).\(info.fieldName).")
@@ -889,7 +890,7 @@ func completeValue(
889890
}
890891
}
891892

892-
return result.flatMap(to: Any?.self) { result -> EventLoopFuture<Any?> in
893+
return result.flatMap(to: Any?.self) { result -> Future<Any?> in
893894
// If result value is null-ish (nil or .null) then return .null.
894895
guard let result = result, let r = unwrap(result) else {
895896
return exeContext.eventLoopGroup.next().newSucceededFuture(result: nil)
@@ -955,7 +956,7 @@ func completeListValue(
955956
info: GraphQLResolveInfo,
956957
path: IndexPath,
957958
result: Any
958-
) throws -> EventLoopFuture<[Any?]> {
959+
) throws -> Future<[Any?]> {
959960
guard let result = result as? [Any?] else {
960961
throw GraphQLError(
961962
message:
@@ -965,21 +966,21 @@ func completeListValue(
965966
}
966967

967968
let itemType = returnType.ofType
968-
var completedResults: [EventLoopFuture<Any?>] = []
969+
var completedResults: [Future<Any?>] = []
969970

970971
for (index, item) in result.enumerated() {
971972
// No need to modify the info object containing the path,
972973
// since from here on it is not ever accessed by resolver funcs.
973974
let fieldPath = path.appending(index)
974-
let futureItem = item as? EventLoopFuture<Any?> ?? exeContext.eventLoopGroup.next().newSucceededFuture(result: item)
975+
let futureItem = item as? Future<Any?> ?? exeContext.eventLoopGroup.next().newSucceededFuture(result: item)
975976

976977
let completedItem = try completeValueCatchingError(
977978
exeContext: exeContext,
978979
returnType: itemType,
979980
fieldASTs: fieldASTs,
980981
info: info,
981982
path: fieldPath,
982-
result: .result(futureItem)
983+
result: .success(futureItem)
983984
)
984985

985986
completedResults.append(completedItem)
@@ -1022,7 +1023,7 @@ func completeAbstractValue(
10221023
info: GraphQLResolveInfo,
10231024
path: IndexPath,
10241025
result: Any
1025-
) throws -> EventLoopFuture<Any?> {
1026+
) throws -> Future<Any?> {
10261027
var resolveRes = try returnType.resolveType?(result, exeContext.eventLoopGroup, info).typeResolveResult
10271028

10281029
resolveRes = try resolveRes ?? defaultResolveType(
@@ -1088,7 +1089,7 @@ func completeObjectValue(
10881089
info: GraphQLResolveInfo,
10891090
path: IndexPath,
10901091
result: Any
1091-
) throws -> EventLoopFuture<Any?> {
1092+
) throws -> Future<Any?> {
10921093
// If there is an isTypeOf predicate func, call it with the
10931094
// current result. If isTypeOf returns false, then raise an error rather
10941095
// than continuing execution.
@@ -1122,7 +1123,7 @@ func completeObjectValue(
11221123
sourceValue: result,
11231124
path: path,
11241125
fields: subFieldASTs
1125-
).map { $0 }
1126+
).map { $0 }
11261127
}
11271128

11281129
/**
@@ -1156,7 +1157,7 @@ func defaultResolve(
11561157
context: Any,
11571158
eventLoopGroup: EventLoopGroup,
11581159
info: GraphQLResolveInfo
1159-
) -> EventLoopFuture<Any?> {
1160+
) -> Future<Any?> {
11601161
#warning("Why not mark function as throwing?")
11611162

11621163
guard let source = unwrap(source) else {

0 commit comments

Comments
 (0)