Skip to content

Allow configuration of CoroutineContextProvider so that context can b… #247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.coxautodev.graphql.tools;

import kotlin.coroutines.CoroutineContext;

public interface CoroutineContextProvider {
CoroutineContext provide();
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceReso
val args = this.args.map { it(environment) }.toTypedArray()

return if (isSuspendFunction) {
GlobalScope.future(options.coroutineContext) {
GlobalScope.future(options.coroutineContextProvider.provide()) {
methodAccess.invokeSuspend(source, methodIndex, args)?.transformWithGenericWrapper(environment)
}
} else {
Expand Down
29 changes: 19 additions & 10 deletions src/main/kotlin/com/coxautodev/graphql/tools/SchemaParserBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ import com.google.common.collect.HashBiMap
import com.google.common.collect.Maps
import graphql.language.Definition
import graphql.language.Document
import graphql.language.FieldDefinition
import graphql.language.ListType
import graphql.language.NonNullType
import graphql.language.ObjectTypeDefinition
import graphql.language.TypeName
import graphql.parser.Parser
import graphql.schema.DataFetchingEnvironment
import graphql.schema.GraphQLScalarType
Expand Down Expand Up @@ -288,7 +283,7 @@ data class SchemaParserOptions internal constructor(
val proxyHandlers: List<ProxyHandler>,
val preferGraphQLResolver: Boolean,
val introspectionEnabled: Boolean,
val coroutineContext: CoroutineContext,
val coroutineContextProvider: CoroutineContextProvider,
val typeDefinitionFactories: List<TypeDefinitionFactory>
) {
companion object {
Expand All @@ -299,6 +294,9 @@ data class SchemaParserOptions internal constructor(
fun defaultOptions() = Builder().build()
}

val coroutineContext: CoroutineContext
get() = coroutineContextProvider.provide()

class Builder {
private var contextClass: Class<*>? = null
private val genericWrappers: MutableList<GenericWrapper> = mutableListOf()
Expand All @@ -308,6 +306,7 @@ data class SchemaParserOptions internal constructor(
private val proxyHandlers: MutableList<ProxyHandler> = mutableListOf(Spring4AopProxyHandler(), GuiceAopProxyHandler(), JavassistProxyHandler(), WeldProxyHandler())
private var preferGraphQLResolver = false
private var introspectionEnabled = true
private var coroutineContextProvider: CoroutineContextProvider? = null
private var coroutineContext: CoroutineContext? = null
private var typeDefinitionFactories: MutableList<TypeDefinitionFactory> = mutableListOf(RelayConnectionFactory())

Expand Down Expand Up @@ -360,7 +359,11 @@ data class SchemaParserOptions internal constructor(
}

fun coroutineContext(context: CoroutineContext) = this.apply {
this.coroutineContext = context
this.coroutineContextProvider = DefaultCoroutineContextProvider(context)
}

fun coroutineContextProvider(contextProvider: CoroutineContextProvider) = this.apply {
this.coroutineContextProvider = contextProvider
}

fun typeDefinitionFactory(factory: TypeDefinitionFactory) = this.apply {
Expand All @@ -369,15 +372,15 @@ data class SchemaParserOptions internal constructor(

@ExperimentalCoroutinesApi
fun build(): SchemaParserOptions {
val coroutineContext = coroutineContext ?: Dispatchers.Default
val coroutineContextProvider = coroutineContextProvider ?: DefaultCoroutineContextProvider(Dispatchers.Default)
val wrappers = if (useDefaultGenericWrappers) {
genericWrappers + listOf(
GenericWrapper(Future::class, 0),
GenericWrapper(CompletableFuture::class, 0),
GenericWrapper(CompletionStage::class, 0),
GenericWrapper(Publisher::class, 0),
GenericWrapper.withTransformer(ReceiveChannel::class, 0, { receiveChannel ->
GlobalScope.publish(coroutineContext) {
GlobalScope.publish(coroutineContextProvider.provide()) {
try {
for (item in receiveChannel) {
send(item)
Expand All @@ -393,7 +396,13 @@ data class SchemaParserOptions internal constructor(
}

return SchemaParserOptions(contextClass, wrappers, allowUnimplementedResolvers, objectMapperProvider,
proxyHandlers, preferGraphQLResolver, introspectionEnabled, coroutineContext, typeDefinitionFactories)
proxyHandlers, preferGraphQLResolver, introspectionEnabled, coroutineContextProvider, typeDefinitionFactories)
}
}

internal class DefaultCoroutineContextProvider(val coroutineContext: CoroutineContext): CoroutineContextProvider {
override fun provide(): CoroutineContext {
return coroutineContext
}
}

Expand Down