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

@BatchMapping methods should pass the localContext as the BatchLoaderEnvironment's keyContexts #1066

Closed
ooraini opened this issue Oct 12, 2024 · 4 comments
Assignees
Labels
in: core Issues related to config and core support status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement
Milestone

Comments

@ooraini
Copy link

ooraini commented Oct 12, 2024

calling getKeyContexts on BatchLoaderEnvironment returns a list of nulls. I think this is caused by Spring's BatchMappingDataFetcher not propagating the local context. Specifically line 606:

static class BatchMappingDataFetcher implements DataFetcher<Object>, SelfDescribingDataFetcher<Object> {

		private final DataFetcherMappingInfo mappingInfo;

		private final ResolvableType returnType;

		private final String dataLoaderKey;

		BatchMappingDataFetcher(DataFetcherMappingInfo info, ResolvableType valueType, String dataLoaderKey) {
			this.mappingInfo = info;
			this.returnType = ResolvableType.forClassWithGenerics(CompletableFuture.class, valueType);
			this.dataLoaderKey = dataLoaderKey;
		}

		@Override
		public String getDescription() {
			return "@BatchMapping " + this.mappingInfo.getHandlerMethod().getShortLogMessage();
		}

		@Override
		public ResolvableType getReturnType() {
			return this.returnType;
		}

		@Override
		public Object get(DataFetchingEnvironment env) {
			DataLoader<?, ?> dataLoader = env.getDataLoaderRegistry().getDataLoader(this.dataLoaderKey);
			Assert.state(dataLoader != null, "No DataLoader for key '" + this.dataLoaderKey + "'");
			return dataLoader.load(env.getSource()); <-- HERE
		}

		@Override
		public String toString() {
			return getDescription();
		}
	}

Changing it to: return dataLoader.load(env.getSource(), env.getLocalContext()) might fix the issue.(I think)

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 12, 2024
@bclozel bclozel self-assigned this Oct 16, 2024
@bclozel
Copy link
Member

bclozel commented Oct 16, 2024

Thanks for reaching out @ooraini .

I'm not sure I understand the problem here. Rather than pointing to a possible fix, could you explain what you're doing and where you're getting the BatchLoaderEnvironment from? Maybe share a sample controller that demonstrates the problem or better, a minimal sample application?

Here, this part of our codebase is about registering @BatchMapping controller methods, and I don't see the link with BatchLoaderEnvironment and what you would expect the key contexts to contain. The fix you're suggesting seems to go against the API, because I think getKeyContexts should return a Map<String, GraphQLContext>.

@bclozel bclozel added status: waiting-for-feedback We need additional information before we can continue in: core Issues related to config and core support labels Oct 16, 2024
@ooraini
Copy link
Author

ooraini commented Oct 17, 2024

Apologies, I meant to refer to the getKeyContextsList method. Here is an example. Suppose I have the following SchemaMapping:

    @SchemaMapping(typeName = "ShareholderRegisterShareholder")
    S3ObjectRef certificate(ShareholderProjection projection,
                            @LocalContextValue ShareholderRegisterProjection register,
                            @LocalContextValue Company company) {
         // ...more code
    }

I'm using two values from the local context. Things work. Now, I want to optimize it by processing fields in batch using BatchMapping. I was hoping that the following would work:

    @BatchMapping(typeName = "ShareholderRegisterShareholder")
    Map<LegalPersonIdentifier, S3ObjectRef> certificate(List<ShareholderProjection> projections,
                                                        BatchLoaderEnvironment environment) {
        List<Object> keyContextsList = environment.getKeyContextsList();
        for (int i = 0, projectionsSize = projections.size(); i < projectionsSize; i++) {
            ShareholderProjection projection = projections.get(i);
            GraphQLContext graphQLContext = (GraphQLContext) keyContextsList.get(i);
            Company company = graphQLContext.get("company");
            ShareholderRegisterProjection register = graphQLContext.get("register");

            // do stuff, e.g. group the data and batch process it

        }
    }

But, the getKeyContextsList is returning a list of null elements. I traced back the execution into graphql-java and the datalaoder library until I got to BatchMappingDataFetcher.

what you would expect the key contexts to contain

I expect(hope?) getKeyContextsList to contain the local context for each source object in List<SOURCE>.

Hope that helps.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Oct 17, 2024
@bclozel bclozel added type: bug A general bug and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Oct 17, 2024
@bclozel bclozel added this to the 1.2.9 milestone Oct 17, 2024
@bclozel bclozel changed the title Propagate local context to DataLoader @BatchMapping methods do not propagate GraphQL context to DataLoader Oct 17, 2024
@bclozel bclozel modified the milestones: 1.2.9, 1.3.3 Oct 17, 2024
@bclozel bclozel added the for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x label Oct 17, 2024
@github-actions github-actions bot added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x labels Oct 17, 2024
@bclozel
Copy link
Member

bclozel commented Oct 17, 2024

Thanks for the additional info @ooraini that made perfect sense. This should be fixed in SNAPSHOTs shortly. We have scheduled a set of maintenance versions on Tuesday.

@rstoyanchev rstoyanchev changed the title @BatchMapping methods do not propagate GraphQL context to DataLoader @BatchMapping methods should pass the localContext as the BatchLoaderEnvironment's keyContexts Oct 21, 2024
@rstoyanchev rstoyanchev added type: enhancement A general enhancement and removed type: bug A general bug labels Oct 21, 2024
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Oct 21, 2024

I've changed this to an enhancement as the current behavior was intentional, see #232 (comment) for previous discussions.

rstoyanchev added a commit that referenced this issue Oct 21, 2024
rstoyanchev added a commit that referenced this issue Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues related to config and core support status: backported An issue that has been backported to maintenance branches type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants