-
Notifications
You must be signed in to change notification settings - Fork 36
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
Query batching fails #22
Comments
Just updated my branch to use postgres, which gives different result. Reproduction commit: https://github.com/josephktcheung/typescript-advanced-example/tree/91ccd7bad62d87ab8c1d3b47a446814f413ddbf1 Here is updated import { bootstrap } from "vesper";
import { PostController } from "./controller/PostController";
import { Post } from "./entity/Post";
import { CategoryController } from "./controller/CategoryController";
import { Category } from "./entity/Category";
import { PostResolver } from "./resolver/PostResolver";
import { createApolloFetch } from 'apollo-fetch';
import { getConnection } from "typeorm";
const apolloFetch = createApolloFetch({ uri: 'http://localhost:3000/graphql' });
const generateRequest = name => ({
"operationName": "CreateCategory",
"query": `mutation CreateCategory {\n categorySave(name: \"${name}\") {name}}\n`
});
const run = async () => {
const single = await apolloFetch(generateRequest('single'));
console.log('single request result: ', JSON.stringify(single, null, 2));
const multiple = await apolloFetch([generateRequest('multiple 1'), generateRequest('multiple 2')]);
console.log('multiple requests result: ', JSON.stringify(multiple, null, 2));
}
const checkPersistence = async () => {
const categoryRepository = getConnection().manager.getRepository(Category);
const categories = await categoryRepository.find();
console.log('categories persisted in db: ', JSON.stringify(categories, null, 2));
}
bootstrap({
port: 3000,
controllers: [
PostController,
CategoryController
],
resolvers: [
PostResolver
],
entities: [
Post,
Category
],
schemas: [__dirname + "/schema/**/*.graphql"]
}).then(() => {
console.log("Your app is up and running on http://localhost:3000 . " +
"You can use Playground in development mode on http://localhost:3000/playground");
return run();
}).then(() => {
return checkPersistence();
})
.catch(error => {
console.error(error.stack ? error.stack : error);
}); And here's console log:
You can see that this time multiple requests result shows up, but if you run a query against the database only records in single request are persisted, which is very misleading. |
I hope Vesper can support query batching soon. Because I'm running Vesper on aws lambda, and with batching I can reduce number of times lambda get called, which means reducing our cost. ATM I need to set our batch size to 1 in our client const httpLink = new BatchHttpLink({
uri: process.env.GRAPHQL_ENDPOINT,
credentials: 'same-origin',
batchMax: 1,
}); |
After further investigation, the problem is more serious than I thought. Here's the latest reproduction commit: https://github.com/josephktcheung/typescript-advanced-example/tree/817468b030572e8447fccace3da5480510dc8ef1 Here's my new import { bootstrap } from "vesper";
import { PostController } from "./controller/PostController";
import { Post } from "./entity/Post";
import { CategoryController } from "./controller/CategoryController";
import { Category } from "./entity/Category";
import { PostResolver } from "./resolver/PostResolver";
import { createApolloFetch } from 'apollo-fetch';
import { getConnection } from "typeorm";
const apolloFetch = createApolloFetch({ uri: 'http://localhost:3000/graphql' });
const generateRequest = name => ({
"operationName": "CreateCategory",
"query": `mutation CreateCategory {\n categorySave(name: \"${name}\") {name}}\n`
});
const run = async () => {
const single = await apolloFetch(generateRequest('single'));
console.log('single request result: ', JSON.stringify(single, null, 2));
const batch = await apolloFetch([generateRequest('batch 1'), generateRequest('batch 2')]);
console.log('batch requests result: ', JSON.stringify(batch, null, 2));
const asynchronous = await Promise.all([
apolloFetch(generateRequest('asynchronous 1')), apolloFetch(generateRequest('asynchronous 2'))
]);
console.log('asynchronous requests result: ', JSON.stringify(asynchronous, null, 2));
}
const checkPersistence = async () => {
const categoryRepository = getConnection().manager.getRepository(Category);
const categories = await categoryRepository.find();
console.log('categories persisted in db: ', JSON.stringify(categories, null, 2));
}
bootstrap({
port: 3000,
controllers: [
PostController,
CategoryController
],
resolvers: [
PostResolver
],
entities: [
Post,
Category
],
schemas: [__dirname + "/schema/**/*.graphql"]
}).then(() => {
console.log("Your app is up and running on http://localhost:3000 . " +
"You can use Playground in development mode on http://localhost:3000/playground");
return run();
}).then(() => {
return checkPersistence();
})
.catch(error => {
console.error(error.stack ? error.stack : error);
}); And here's console logs:
Even if I run |
This means if the client sends multiple mutation requests to the server at the same time the server cannot handle them at all, not even a single one, no matter those requests are batched or not. This is a deal breaker to me tbh. I’ll try diving into source code to find out why. |
So this is because by default |
This makes me wonder if I understand that making every mutation transactional has its merits, but the current implementation makes it impossible to perform asynchronous / batch mutations if the batch includes more than 1 transactional mutation, even if 2 mutations are different e.g. What do you think @pleerock ? |
I'm using
apollo-link-batch-http
to batch our graphql request but Vesper fails to run batched mutations.Reproduction commit: https://github.com/josephktcheung/typescript-advanced-example/tree/a773ce11bc45890720b24fe432403dbee6463e7c
Steps:
typescript-advanced-example
and upgradedvesper
to latestindex.ts
:The text was updated successfully, but these errors were encountered: