Skip to content

Commit d4e3ba4

Browse files
WIP: working state - dirty
1 parent 3403589 commit d4e3ba4

3 files changed

Lines changed: 77 additions & 17 deletions

File tree

src/main/java/graphql/execution/MergedField.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ public List<DeferredExecution> getDeferredExecutions() {
139139
return deferredExecutions;
140140
}
141141

142+
/**
143+
* TODO Javadoc
144+
* @return
145+
*/
146+
@ExperimentalApi
147+
public boolean isDeferred() {
148+
return !deferredExecutions.isEmpty();
149+
}
150+
142151
public static Builder newMergedField() {
143152
return new Builder();
144153
}

src/main/java/graphql/execution/instrumentation/dataloader/PerLevelDataLoaderDispatchStrategy.java

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import graphql.execution.ExecutionContext;
77
import graphql.execution.ExecutionStrategyParameters;
88
import graphql.execution.FieldValueInfo;
9+
import graphql.execution.MergedField;
910
import graphql.schema.DataFetcher;
1011
import graphql.util.LockKit;
1112
import org.dataloader.DataLoaderRegistry;
1213

1314
import java.util.Collections;
1415
import java.util.LinkedHashSet;
1516
import java.util.List;
17+
import java.util.Optional;
1618
import java.util.Set;
1719
import java.util.concurrent.atomic.AtomicBoolean;
1820

@@ -32,6 +34,8 @@ private static class CallStack {
3234
private final LevelMap happenedStrategyCallsPerLevel = new LevelMap();
3335
private final LevelMap happenedOnFieldValueCallsPerLevel = new LevelMap();
3436

37+
private final LevelMap expectedDeferredFetchCountPerLevel = new LevelMap();
38+
private final LevelMap deferredFetchCountPerLevel = new LevelMap();
3539
private final LevelMap expectedDeferredStrategyCallsPerLevel = new LevelMap();
3640
private final LevelMap happenedOnDeferredFieldValueCallsPerLevel = new LevelMap();
3741

@@ -47,10 +51,18 @@ void increaseExpectedFetchCount(int level, int count) {
4751
expectedFetchCountPerLevel.increment(level, count);
4852
}
4953

54+
void increaseExpectedDeferredFetchCount(int level, int count) {
55+
expectedDeferredFetchCountPerLevel.increment(level, count);
56+
}
57+
5058
void increaseFetchCount(int level) {
5159
fetchCountPerLevel.increment(level, 1);
5260
}
5361

62+
void increaseDeferredFetchCount(int level) {
63+
deferredFetchCountPerLevel.increment(level, 1);
64+
}
65+
5466
void increaseExpectedStrategyCalls(int level, int count) {
5567
expectedStrategyCallsPerLevel.increment(level, count);
5668
}
@@ -90,7 +102,8 @@ private boolean hasDeferredCalls() {
90102
}
91103

92104
private boolean hasDeferredCalls(int level) {
93-
return expectedDeferredStrategyCallsPerLevel.get(level) > 0 || happenedOnDeferredFieldValueCallsPerLevel.get(level) > 0;
105+
return expectedDeferredStrategyCallsPerLevel.get(level) > 0 || happenedOnDeferredFieldValueCallsPerLevel.get(level) > 0 ||
106+
deferredFetchCountPerLevel.get(level) > 0 || expectedDeferredFetchCountPerLevel.get(level) > 0;
94107
}
95108

96109
@Override
@@ -104,13 +117,15 @@ public String toString() {
104117
", de=" + expectedDeferredStrategyCallsPerLevel +
105118
", dh=" + happenedOnDeferredFieldValueCallsPerLevel +
106119
", dl" + dispatchedLevels +
120+
", edc=" + expectedDeferredFetchCountPerLevel +
121+
", dc=" + deferredFetchCountPerLevel +
107122
'}';
108123
}
109124

110125

111126
public boolean dispatchIfNotDispatchedBefore(int level, String origin) {
112127
if (dispatchedLevels.contains(level)) {
113-
if(this.hasDeferredCalls(level - 1)) {
128+
if(this.hasDeferredCalls(level) || this.hasDeferredCalls(level - 1)) {
114129
System.out.println("df: " + level + " already dispatched.");
115130
return true;
116131
}
@@ -128,8 +143,8 @@ public PerLevelDataLoaderDispatchStrategy(ExecutionContext executionContext) {
128143
}
129144

130145
@Override
131-
public void deferredField(FieldValueInfo fieldValueInfo, ExecutionStrategyParameters executionStrategyParameters) {
132-
int curLevel = executionStrategyParameters.getExecutionStepInfo().getPath().getLevel() + 1;
146+
public void deferredField(FieldValueInfo fieldValueInfo, ExecutionStrategyParameters parameters) {
147+
int curLevel = parameters.getExecutionStepInfo().getPath().getLevel() + 1;
133148

134149
boolean dispatchNeeded = callStack.lock.callLocked(() -> {
135150
callStack.increaseHappenedOnDeferredFieldValueCalls(curLevel);
@@ -142,7 +157,7 @@ public void deferredField(FieldValueInfo fieldValueInfo, ExecutionStrategyParame
142157
System.out.println(
143158
"df: " + curLevel + " :: " +
144159
callStack + " :: " +
145-
executionStrategyParameters.getPath() + " :: "
160+
parameters.getPath() + " :: "
146161
);
147162

148163
// return false;
@@ -152,6 +167,8 @@ public void deferredField(FieldValueInfo fieldValueInfo, ExecutionStrategyParame
152167
if (dispatchNeeded) {
153168
dispatch(curLevel);
154169
}
170+
171+
// onFieldValuesInfoDispatchIfNeeded(Collections.singletonList(fieldValueInfo), curLevel, parameters, "df");
155172
}
156173

157174
@Override
@@ -169,8 +186,8 @@ public void executionStrategyOnFieldValuesInfo(List<FieldValueInfo> fieldValueIn
169186
}
170187

171188
@Override
172-
public void executionStrategyOnFieldValuesException(Throwable t, ExecutionStrategyParameters executionStrategyParameters) {
173-
int curLevel = executionStrategyParameters.getPath().getLevel() + 1;
189+
public void executionStrategyOnFieldValuesException(Throwable t, ExecutionStrategyParameters parameters) {
190+
int curLevel = parameters.getPath().getLevel() + 1;
174191
callStack.lock.runLocked(() ->
175192
callStack.increaseHappenedOnFieldValueCalls(curLevel)
176193
);
@@ -207,17 +224,24 @@ public void executeObjectOnFieldValuesException(Throwable t, ExecutionStrategyPa
207224
}
208225

209226

210-
private void increaseCallCounts(int curLevel, ExecutionStrategyParameters executionStrategyParameters, String origin) {
211-
int fieldCount = executionStrategyParameters.getFields().size();
227+
private void increaseCallCounts(int curLevel, ExecutionStrategyParameters parameters, String origin) {
228+
int fieldCount = parameters.getFields().size();
229+
230+
int deferredFieldCount = (int) parameters.getFields().getSubFieldsList().stream()
231+
.filter(MergedField::isDeferred)
232+
.count();
233+
212234
callStack.lock.runLocked(() -> {
213-
callStack.increaseExpectedFetchCount(curLevel, fieldCount);
235+
callStack.increaseExpectedFetchCount(curLevel, fieldCount - deferredFieldCount);
236+
callStack.increaseExpectedDeferredFetchCount(curLevel, deferredFieldCount);
214237
callStack.increaseHappenedStrategyCalls(curLevel);
215238
});
216239

240+
217241
System.out.println(
218242
origin + ": " + curLevel + " :: " +
219243
callStack + " :: " +
220-
executionStrategyParameters.getPath()
244+
parameters.getPath()
221245
);
222246
}
223247

@@ -234,9 +258,17 @@ private void onFieldValuesInfoDispatchIfNeeded(List<FieldValueInfo> fieldValueIn
234258
// thread safety: called with callStack.lock
235259
//
236260
private boolean handleOnFieldValuesInfo(List<FieldValueInfo> fieldValueInfos, int curLevel, String origin, ExecutionStrategyParameters parameters) {
237-
callStack.increaseHappenedOnFieldValueCalls(curLevel);
261+
boolean isDeferred = Optional.ofNullable(parameters.getField()).map(MergedField::isDeferred).orElse(false);
262+
238263
int expectedStrategyCalls = getCountForList(fieldValueInfos);
239-
callStack.increaseExpectedStrategyCalls(curLevel + 1, expectedStrategyCalls);
264+
if(isDeferred) {
265+
System.out.println("deffZ");
266+
callStack.increaseExpectedDeferredStrategyCalls(10+curLevel + 1, expectedStrategyCalls);
267+
callStack.increaseHappenedOnDeferredFieldValueCalls(10+curLevel);
268+
} else {
269+
callStack.increaseExpectedStrategyCalls(curLevel + 1, expectedStrategyCalls);
270+
callStack.increaseHappenedOnFieldValueCalls(curLevel);
271+
}
240272

241273
System.out.println(
242274
origin + ": " + curLevel + " :: " +
@@ -262,19 +294,24 @@ private int getCountForList(List<FieldValueInfo> fieldValueInfos) {
262294

263295
@Override
264296
public void fieldFetched(ExecutionContext executionContext,
265-
ExecutionStrategyParameters executionStrategyParameters,
297+
ExecutionStrategyParameters parameters,
266298
DataFetcher<?> dataFetcher,
267299
Object fetchedValue) {
268-
int level = executionStrategyParameters.getPath().getLevel();
300+
int level = parameters.getPath().getLevel();
301+
boolean isDeferred = parameters.getField().isDeferred();
269302
boolean dispatchNeeded = callStack.lock.callLocked(() -> {
270-
callStack.increaseFetchCount(level);
303+
if(isDeferred) {
304+
callStack.increaseDeferredFetchCount(level);
305+
} else {
306+
callStack.increaseFetchCount(level);
307+
}
271308
return dispatchIfNeeded(level, "ff");
272309
});
273310

274311
System.out.println(
275312
"ff: " + level + " :: " +
276313
callStack + " :: " +
277-
executionStrategyParameters.getPath() + " :: " +
314+
parameters.getPath() + " :: " +
278315
fetchedValue
279316
);
280317

src/test/groovy/graphql/execution/instrumentation/dataloader/DeferWithDataLoaderTest.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ class DeferWithDataLoaderTest extends Specification {
4747
def "query with single deferred field"() {
4848
given:
4949
def query = getQuery(true, false)
50+
// def defer = true
51+
// def query = """
52+
// query {
53+
// shops {
54+
// name
55+
// ... @defer(if: $defer) {
56+
// departments {
57+
// name
58+
// }
59+
// }
60+
// }
61+
// }
62+
//
63+
// """
5064

5165
def expectedInitialData = [
5266
data : [

0 commit comments

Comments
 (0)