@@ -38,7 +38,7 @@ func subscribe(
3838 operationName: String ? = nil ,
3939 fieldResolver: GraphQLFieldResolve ,
4040 subscribeFieldResolver: GraphQLFieldResolve
41- ) -> EventLoopFuture < Any ? > { // This is either an AsyncIterator or a GraphQLResult
41+ ) -> EventLoopFuture < SubscriptionResult > {
4242
4343
4444 let sourceFuture = createSourceEventStream (
@@ -77,16 +77,18 @@ func subscribe(
7777 operationName: operationName
7878 )
7979 }
80- return sourceFuture. flatMap ( { ( resultOrStream) -> EventLoopFuture < Any ? > in
81- if resultOrStream is GraphQLResult { // Return the result directly
82- return eventLoopGroup. next ( ) . makeSucceededFuture ( resultOrStream)
83- } else { // We can assume that it's an AsyncIterable
84- let stream : AsyncIterable < GraphQLResult > ! = resultOrStream
85- return MappedAsyncIterator ( from: stream) { payload -> EventLoopFuture < GraphQLResult > in
86- mapSourceToResponse ( payload: payload)
80+ return sourceFuture. flatMap { subscriptionResult -> EventLoopFuture < SubscriptionResult > in
81+ do {
82+ let subscriptionObserver = try subscriptionResult. get ( )
83+ let eventObserver = subscriptionObserver. map { eventPayload -> GraphQLResult in
84+ return try ! mapSourceToResponse ( payload: eventPayload) . wait ( ) // TODO Remove this wait
8785 }
86+ // TODO Making a future here feels it indicates a mistake...
87+ return eventLoopGroup. next ( ) . makeSucceededFuture ( SubscriptionResult . success ( eventObserver) )
88+ } catch let graphQLError as GraphQLError {
89+ return eventLoopGroup. next ( ) . makeSucceededFuture ( SubscriptionResult . failure ( graphQLError) )
8890 }
89- } )
91+ }
9092}
9193
9294/**
@@ -130,7 +132,7 @@ func createSourceEventStream(
130132 variableValues: [ String : Map ] = [ : ] ,
131133 operationName: String ? = nil ,
132134 subscribeFieldResolver: GraphQLFieldResolve
133- ) -> EventLoopFuture < Any ? > { // This is either an AsyncIterator or a GraphQLResult
135+ ) -> EventLoopFuture < SubscriptionResult > {
134136
135137 let executeStarted = instrumentation. now
136138 let exeContext : ExecutionContext
@@ -168,9 +170,9 @@ func createSourceEventStream(
168170 result: nil
169171 )
170172
171- return eventLoopGroup. next ( ) . makeSucceededFuture ( GraphQLResult ( errors : [ error] ) )
173+ return eventLoopGroup. next ( ) . makeSucceededFuture ( SubscriptionResult . failure ( error) )
172174 } catch {
173- return eventLoopGroup. next ( ) . makeSucceededFuture ( GraphQLResult ( errors : [ GraphQLError ( error) ] ) )
175+ return eventLoopGroup. next ( ) . makeSucceededFuture ( SubscriptionResult . failure ( GraphQLError ( error) ) )
174176 }
175177
176178 return try ! executeSubscription ( context: exeContext, eventLoopGroup: eventLoopGroup)
@@ -179,7 +181,7 @@ func createSourceEventStream(
179181func executeSubscription(
180182 context: ExecutionContext ,
181183 eventLoopGroup: EventLoopGroup
182- ) throws -> EventLoopFuture < Any ? > { // This is either an AsyncIterator or a GraphQLResult
184+ ) throws -> EventLoopFuture < SubscriptionResult > {
183185
184186 // Get the first node
185187 let type = try getOperationRootType ( schema: context. schema, operation: context. operation)
@@ -226,7 +228,7 @@ func executeSubscription(
226228 let contextValue = context. context
227229
228230 // Call the `subscribe()` resolver or the default resolver to produce an
229- // AsyncIterable yielding raw payloads.
231+ // Observable yielding raw payloads.
230232 let resolve = fieldDef. subscribe ?? fieldDef. resolve ?? defaultResolve
231233
232234 // Get the resolve func, regardless of if its result is normal
@@ -247,33 +249,14 @@ func executeSubscription(
247249 info: info,
248250 path: path,
249251 result: result
250- ) . flatMap { value -> EventLoopFuture < Any ? > in
251- if let asyncIterable = value as? EventLoopFuture < AsyncIterable > {
252- return asyncIterable
252+ ) . map { value -> SubscriptionResult in
253+ if let observable = value as? Observable < GraphQLResult > {
254+ return SubscriptionResult . success ( observable )
253255 } else {
254- context. append ( error: GraphQLError ( message: " Subscription field must return AsyncIterable . " ) )
255- return context . eventLoopGroup . next ( ) . makeSucceededFuture ( nil )
256+ context. append ( error: GraphQLError ( message: " Subscription field resolver must return Observable of GraphQLResults . " ) )
257+ return SubscriptionResult . failure ( GraphQLError ( message : " Subscription field resolver must return Observable of GraphQLResults. " ) )
256258 }
257259 }
258260}
259261
260- protocol AsyncIterable {
261- associatedtype Item
262- func next( ) -> EventLoopFuture < Item >
263- }
264-
265- class MappedAsyncIterator < OrigType: AsyncIterable , MappedType> : AsyncIterable {
266- let origIterable : OrigType
267- let callback : ( OrigType . Item ) -> Future < MappedType >
268-
269- init ( from: OrigType , by: @escaping ( OrigType . Item ) -> Future < MappedType > ) {
270- origIterable = from
271- callback = by
272- }
273-
274- func next( ) -> EventLoopFuture < MappedType > {
275- origIterable. next ( ) . flatMap { origResult -> Future < MappedType > in
276- self . callback ( origResult)
277- }
278- }
279- }
262+ typealias SubscriptionResult = Result < Observable < GraphQLResult > , GraphQLError >
0 commit comments