Skip to content
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

Added field fetching method for Expedia #3571

Merged
merged 2 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/java/graphql/execution/ExecutionStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import graphql.execution.directives.QueryDirectivesImpl;
import graphql.execution.incremental.DeferredExecutionSupport;
import graphql.execution.instrumentation.ExecuteObjectInstrumentationContext;
import graphql.execution.instrumentation.FieldFetchingInstrumentationContext;
import graphql.execution.instrumentation.Instrumentation;
import graphql.execution.instrumentation.InstrumentationContext;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters;
Expand Down Expand Up @@ -487,7 +488,7 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
Instrumentation instrumentation = executionContext.getInstrumentation();

InstrumentationFieldFetchParameters instrumentationFieldFetchParams = new InstrumentationFieldFetchParameters(executionContext, dataFetchingEnvironment, parameters, dataFetcher instanceof TrivialDataFetcher);
InstrumentationContext<Object> fetchCtx = nonNullCtx(instrumentation.beginFieldFetch(instrumentationFieldFetchParams,
FieldFetchingInstrumentationContext fetchCtx = FieldFetchingInstrumentationContext.nonNullCtx(instrumentation.beginFieldFetching(instrumentationFieldFetchParams,
executionContext.getInstrumentationState())
);

Expand All @@ -496,6 +497,7 @@ Async.CombinedBuilder<FieldValueInfo> getAsyncFieldValueInfo(
Object fetchedObject = invokeDataFetcher(executionContext, parameters, fieldDef, dataFetchingEnvironment, dataFetcher);
executionContext.getDataLoaderDispatcherStrategy().fieldFetched(executionContext, parameters, dataFetcher, fetchedObject);
fetchCtx.onDispatched();
fetchCtx.onFetchedValue(fetchedObject);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context callback now gets the fetched value

if (fetchedObject instanceof CompletableFuture) {
@SuppressWarnings("unchecked")
CompletableFuture<Object> fetchedValue = (CompletableFuture<Object>) fetchedObject;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package graphql.execution.instrumentation;

import com.google.common.collect.ImmutableList;
import graphql.Assert;
import graphql.ExecutionInput;
import graphql.ExecutionResult;
import graphql.ExperimentalApi;
Expand Down Expand Up @@ -159,7 +158,7 @@ public ExecutionStrategyInstrumentationContext beginExecutionStrategy(Instrument
}
BiFunction<Instrumentation, InstrumentationState, ExecuteObjectInstrumentationContext> mapper = (instrumentation, specificState) -> instrumentation.beginExecuteObject(parameters, specificState);
ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state;
if (instrumentations.size() == 1) {
if (instrumentations.size() == 1) {
return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0));
}
return new ChainedExecuteObjectInstrumentationContext(chainedMapAndDropNulls(chainedInstrumentationState, mapper));
Expand All @@ -182,11 +181,26 @@ public InstrumentationContext<ExecutionResult> beginSubscribedFieldEvent(Instrum
return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldExecution(parameters, specificState));
}

@SuppressWarnings("deprecation")
@Override
public InstrumentationContext<Object> beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldFetch(parameters, specificState));
}

@Override
public FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
if (instrumentations.isEmpty()) {
return FieldFetchingInstrumentationContext.NOOP;
}
BiFunction<Instrumentation, InstrumentationState, FieldFetchingInstrumentationContext> mapper = (instrumentation, specificState) -> instrumentation.beginFieldFetching(parameters, specificState);
ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state;
if (instrumentations.size() == 1) {
return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0));
}
ImmutableList<FieldFetchingInstrumentationContext> objects = chainedMapAndDropNulls(chainedInstrumentationState, mapper);
return new ChainedFieldFetchingInstrumentationContext(objects);
}

@Override
public @Nullable InstrumentationContext<Object> beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) {
return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldCompletion(parameters, specificState));
Expand Down Expand Up @@ -344,8 +358,33 @@ public void onFieldValuesException() {
}
}

private static class ChainedFieldFetchingInstrumentationContext implements FieldFetchingInstrumentationContext {

private final ImmutableList<FieldFetchingInstrumentationContext> contexts;

ChainedFieldFetchingInstrumentationContext(ImmutableList<FieldFetchingInstrumentationContext> contexts) {
this.contexts = contexts;
}

@Override
public void onDispatched() {
contexts.forEach(FieldFetchingInstrumentationContext::onDispatched);
}

@Override
public void onFetchedValue(Object fetchedValue) {
contexts.forEach(context -> context.onFetchedValue(fetchedValue));
}

@Override
public void onCompleted(Object result, Throwable t) {
contexts.forEach(context -> context.onCompleted(result, t));
}
}

private static class ChainedDeferredExecutionStrategyInstrumentationContext implements InstrumentationContext<Object> {


private final List<InstrumentationContext<Object>> contexts;

ChainedDeferredExecutionStrategyInstrumentationContext(List<InstrumentationContext<Object>> contexts) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package graphql.execution.instrumentation;

import graphql.Internal;
import graphql.PublicSpi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@PublicSpi
public interface FieldFetchingInstrumentationContext extends InstrumentationContext<Object> {

@Internal
FieldFetchingInstrumentationContext NOOP = new FieldFetchingInstrumentationContext() {
@Override
public void onDispatched() {
}

@Override
public void onCompleted(Object result, Throwable t) {
}

@Override
public void onFetchedValue(Object fetchedValue) {
}
};

/**
* This creates a no-op {@link InstrumentationContext} if the one pass in is null
*
* @param nullableContext a {@link InstrumentationContext} that can be null
*
* @return a non null {@link InstrumentationContext} that maybe a no-op
*/
@NotNull
@Internal
static FieldFetchingInstrumentationContext nonNullCtx(FieldFetchingInstrumentationContext nullableContext) {
return nullableContext == null ? NOOP : nullableContext;
}

@Internal
static FieldFetchingInstrumentationContext adapter(@Nullable InstrumentationContext<Object> context) {
if (context == null) {
return null;
}
return new FieldFetchingInstrumentationContext() {
@Override
public void onDispatched() {
context.onDispatched();
}

@Override
public void onCompleted(Object result, Throwable t) {
context.onCompleted(result, t);
}

@Override
public void onFetchedValue(Object fetchedValue) {
}
};
}

/**
* This is called back with value fetched for the field.
*
* @param fetchedValue a value that a field's {@link graphql.schema.DataFetcher} returned
*/
default void onFetchedValue(Object fetchedValue) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,31 @@ default InstrumentationContext<Object> beginFieldExecution(InstrumentationFieldP
* @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)}
*
* @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null)
*
* @deprecated use {@link #beginFieldFetching(InstrumentationFieldFetchParameters, InstrumentationState)} instead
*/
@Deprecated(since = "2024-04-18")
@Nullable
default InstrumentationContext<Object> beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
return noOp();
}

/**
* This is called just before a field {@link DataFetcher} is invoked. The {@link FieldFetchingInstrumentationContext#onFetchedValue(Object)}
* callback will be invoked once a value is returned by a {@link DataFetcher} but perhaps before
* its value is completed if it's a {@link CompletableFuture} value.
*
* @param parameters the parameters to this step
* @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)}
*
* @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null)
*/
@Nullable
default FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
InstrumentationContext<Object> ctx = beginFieldFetch(parameters, state);
return FieldFetchingInstrumentationContext.adapter(ctx);
}

/**
* This is called just before the complete field is started.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public InstrumentationContext<Object> beginFieldFetch(InstrumentationFieldFetchP
return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldFetch(parameters, specificState));
}

@Override
public FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) {
return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldFetching(parameters, specificState));
}

@Override
public @Nullable InstrumentationContext<Object> beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) {
return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldCompletion(parameters, specificState));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ public class SimplePerformantInstrumentation implements Instrumentation {
return noOp();
}


@Override
public @Nullable InstrumentationContext<Object> beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) {
return noOp();
Expand Down