List<String> fieldNames = new ArrayList<>(fields.keySet()); List<CompletableFuture<FieldValueInfo>> futures = new ArrayList<>(); List<String> resolvedFields = new ArrayList<>(); for (String fieldName : fieldNames) { MergedField currentField = fields.getSubField(fieldName);
public MergedSelectionSet build() { return new MergedSelectionSet(subFields); }
private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionStrategyParameters parameters) { MergedSelectionSet fields = parameters.getFields(); MergedField firstField = fields.getSubField(fields.getKeys().get(0)); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); }
@Override public MergedSelectionSet get() { return MergedSelectionSet.newMergedSelectionSet().build(); }
public Map<String, MergedField> getSubFields() { return mergedSelectionSet.getSubFields(); }
public List<String> getKeys() { return new ArrayList<>(keySet()); }
private FetchedValue fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, MergedSelectionSet fields, String fieldName) { MergedField currentField = fields.getSubField(fieldName); ExecutionPath fieldPath = parameters.getPath().segment(fieldName); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath)); return fetchField(executionContext, newParameters).join(); }
private List<CompletableFuture<FetchedValueAnalysis>> fetchAndAnalyze(ExecutionContext context, FieldSubSelection fieldSubSelection) { return FpKit.map(fieldSubSelection.getMergedSelectionSet().getSubFieldsList(), mergedField -> fetchAndAnalyzeField(context, fieldSubSelection.getSource(), fieldSubSelection.getLocalContext(), mergedField, fieldSubSelection.getExecutionStepInfo())); }
int parentLevel = path.getLevel(); int curLevel = parentLevel + 1; int fieldCount = parameters.getExecutionStrategyParameters().getFields().size(); synchronized (callStack) { callStack.increaseExpectedFetchCount(curLevel, fieldCount);
/** * Given a selection set this will collect the sub-field selections and return it as a map * * @param parameters the parameters to this method * @param selectionSet the selection set to collect on * * @return a map of the sub field selections */ public MergedSelectionSet collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet) { Map<String, MergedField> subFields = new LinkedHashMap<>(); List<String> visitedFragments = new ArrayList<>(); this.collectFields(parameters, selectionSet, visitedFragments, subFields); return newMergedSelectionSet().subFields(subFields).build(); }
private List<CompletableFuture<List<FetchedValueAnalysis>>> batchFetchForEachSubField(ExecutionContext executionContext, List<FieldSubSelection> fieldSubSelections, MergedSelectionSet mergedSelectionSet) { List<Object> sources = map(fieldSubSelections, FieldSubSelection::getSource); return mapEntries(mergedSelectionSet.getSubFields(), (name, mergedField) -> { List<ExecutionStepInfo> newExecutionStepInfos = newExecutionInfos(executionContext, fieldSubSelections, mergedField); return valueFetcher .fetchBatchedValues(executionContext, sources, mergedField, newExecutionStepInfos) .thenApply(fetchValue -> analyseValues(executionContext, fetchValue, newExecutionStepInfos)); }); }
private Map<String, FetchedValue> fetchFields(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { MergedSelectionSet fields = parameters.getFields(); Map<String, CompletableFuture<FetchedValue>> fetchFutures = new LinkedHashMap<>(); // first fetch every value for (String fieldName : fields.keySet()) { ExecutionStrategyParameters newParameters = newParameters(parameters, fields, fieldName); CompletableFuture<FetchedValue> fetchFuture = fetchField(executionContext, newParameters); fetchFutures.put(fieldName, fetchFuture); } // now wait for all fetches to finish together via this join allOf(fetchFutures.values()).join(); Map<String, FetchedValue> fetchedValues = new LinkedHashMap<>(); fetchFutures.forEach((k, v) -> fetchedValues.put(k, v.join())); return fetchedValues; }
private ExecutionStrategyParameters newParameters(ExecutionStrategyParameters parameters, MergedSelectionSet fields, String fieldName) { MergedField currentField = fields.getSubField(fieldName); ExecutionPath fieldPath = parameters.getPath().segment(fieldName); return parameters .transform(builder -> builder.field(currentField).path(fieldPath)); }
private List<CompletableFuture<FetchedValueAnalysis>> fetchAndAnalyze(ExecutionContext context, FieldSubSelection fieldSubSelection) { return FpKit.map(fieldSubSelection.getMergedSelectionSet().getSubFieldsList(), mergedField -> fetchAndAnalyzeField(context, fieldSubSelection.getSource(), fieldSubSelection.getLocalContext(), mergedField, fieldSubSelection.getExecutionStepInfo())); }
int parentLevel = path.getLevel(); int curLevel = parentLevel + 1; int fieldCount = parameters.getExecutionStrategyParameters().getFields().size(); synchronized (callStack) { callStack.increaseExpectedFetchCount(curLevel, fieldCount);
@Override @SuppressWarnings({"TypeParameterUnusedInFormals","FutureReturnValueIgnored"}) public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { Instrumentation instrumentation = executionContext.getInstrumentation(); InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); InstrumentationContext<ExecutionResult> executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters); MergedSelectionSet fields = parameters.getFields(); List<String> fieldNames = new ArrayList<>(fields.keySet()); CompletableFuture<List<ExecutionResult>> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, index, prevResults) -> { MergedField currentField = fields.getSubField(fieldName); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath)); return resolveField(executionContext, newParameters); }); CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>(); executionStrategyCtx.onDispatched(overallResult); resultsFuture.whenComplete(handleResults(executionContext, fieldNames, overallResult)); overallResult.whenComplete(executionStrategyCtx::onCompleted); return overallResult; }
private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionStrategyParameters parameters) { MergedSelectionSet fields = parameters.getFields(); MergedField firstField = fields.getSubField(fields.getKeys().get(0)); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); }
@Override public MergedSelectionSet get() { // by having a .get() method we get lazy evaluation. computeValuesLazily(); return MergedSelectionSet.newMergedSelectionSet().subFields(selectionSetFields).build(); }
@SuppressWarnings("UnnecessaryLocalVariable") private List<ExecutionNode> handleObject(ExecutionContext executionContext, Map<String, Object> argumentValues, FetchedValues fetchedValues, String fieldName, MergedField fields, ExecutionStepInfo executionStepInfo) { // collect list of values by actual type (needed because of interfaces and unions) Map<GraphQLObjectType, List<MapOrList>> resultsByType = new LinkedHashMap<>(); Map<GraphQLObjectType, List<Object>> sourceByType = new LinkedHashMap<>(); for (FetchedValue value : fetchedValues.getValues()) { MapOrList mapOrList = value.getParentResult(); if (value.getValue() == null) { mapOrList.putOrAdd(fieldName, null); continue; } MapOrList childResult = mapOrList.createAndPutMap(fieldName); GraphQLObjectType resolvedType = getGraphQLObjectType(executionContext, fields, executionStepInfo.getUnwrappedNonNullType(), value.getValue(), argumentValues); resultsByType.putIfAbsent(resolvedType, new ArrayList<>()); resultsByType.get(resolvedType).add(childResult); sourceByType.putIfAbsent(resolvedType, new ArrayList<>()); sourceByType.get(resolvedType).add(value.getValue()); } List<ExecutionNode> childNodes = new ArrayList<>(); for (GraphQLObjectType resolvedType : resultsByType.keySet()) { List<MapOrList> results = resultsByType.get(resolvedType); List<Object> sources = sourceByType.get(resolvedType); MergedSelectionSet childFields = getChildFields(executionContext, resolvedType, fields); ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedType); childNodes.add(new ExecutionNode(resolvedType, newExecutionStepInfo, childFields.getSubFields(), results, sources)); } return childNodes; }
public List<String> getKeys() { return new ArrayList<>(keySet()); }