diff --git a/modules/core/src/main/scala/sangria/execution/FieldCollector.scala b/modules/core/src/main/scala/sangria/execution/FieldCollector.scala index ec709283..5c92e151 100644 --- a/modules/core/src/main/scala/sangria/execution/FieldCollector.scala +++ b/modules/core/src/main/scala/sangria/execution/FieldCollector.scala @@ -4,8 +4,8 @@ import sangria.ast.OperationType import sangria.ast.SourceMapper import sangria.schema._ import sangria.ast -import sangria.util.Cache +import java.util.concurrent.ConcurrentHashMap import scala.collection.mutable.{ArrayBuffer, Map => MutableMap, Set => MutableSet} import scala.util.{Failure, Success, Try} @@ -18,23 +18,30 @@ class FieldCollector[Ctx, Val]( exceptionHandler: ExceptionHandler) { private val resultCache = - Cache.empty[(ExecutionPath.PathCacheKeyReversed, String), Try[CollectedFields]] + new ConcurrentHashMap[ + ExecutionPath.PathCacheKeyReversed, + ConcurrentHashMap[String, Try[CollectedFields]]] def collectFields( path: ExecutionPath, tpe: ObjectType[Ctx, _], selections: Vector[ast.SelectionContainer]): Try[CollectedFields] = - resultCache.getOrElseUpdate( - path.cacheKeyReversed -> tpe.name, { - val builder: Try[CollectedFieldsBuilder] = Success(new CollectedFieldsBuilder) + resultCache + .computeIfAbsent( + path.cacheKeyReversed, + key => new ConcurrentHashMap[String, Try[CollectedFields]]) + .computeIfAbsent( + tpe.name, + name => { + val builder: Try[CollectedFieldsBuilder] = Success(new CollectedFieldsBuilder) - selections.foldLeft(builder) { case (acc, s) => - collectFieldsInternal(tpe, s.selections, MutableSet.empty, acc) - } + selections.foldLeft(builder) { case (acc, s) => + collectFieldsInternal(tpe, s.selections, MutableSet.empty, acc) + } - builder.map(_.build) - } - ) + builder.map(_.build) + } + ) private def collectFieldsInternal( tpe: ObjectType[Ctx, _], diff --git a/modules/core/src/main/scala/sangria/execution/ValueCollector.scala b/modules/core/src/main/scala/sangria/execution/ValueCollector.scala index a5ac3518..cd30b40d 100644 --- a/modules/core/src/main/scala/sangria/execution/ValueCollector.scala +++ b/modules/core/src/main/scala/sangria/execution/ValueCollector.scala @@ -8,6 +8,7 @@ import sangria.schema._ import sangria.util.Cache import sangria.validation._ +import java.util.concurrent.ConcurrentHashMap import scala.collection.immutable.VectorBuilder import scala.util.{Failure, Success, Try} @@ -24,7 +25,9 @@ class ValueCollector[Ctx, Input]( new ValueCoercionHelper[Ctx](sourceMapper, deprecationTracker, Some(userContext)) private val argumentCache = - Cache.empty[(ExecutionPath.PathCacheKeyReversed, Vector[ast.Argument]), Try[Args]] + new ConcurrentHashMap[ + ExecutionPath.PathCacheKeyReversed, + ConcurrentHashMap[Vector[ast.Argument], Try[Args]]] def getVariableValues( definitions: Vector[ast.VariableDefinition], @@ -106,9 +109,13 @@ class ValueCollector[Ctx, Input]( if (argumentDefs.isEmpty) ValueCollector.emptyArgs else - argumentCache.getOrElseUpdate( - path.cacheKeyReversed -> argumentAsts, - getArgumentValues(forAstNode, argumentDefs, argumentAsts, variables)) + argumentCache + .computeIfAbsent( + path.cacheKeyReversed, + key => new ConcurrentHashMap[Vector[ast.Argument], Try[Args]]) + .computeIfAbsent( + argumentAsts, + argumentAsts => getArgumentValues(forAstNode, argumentDefs, argumentAsts, variables)) def getArgumentValues( forAstNode: Option[ast.AstNode],