fenos / graphql-thinky

GraphQL & Relay powered by thinky / RethinkDB. https://graphql-thinky.readme.io/
MIT License
75 stars 10 forks source link

Stale data after calling a mutation and then querying? #16

Closed deep-c closed 7 years ago

deep-c commented 7 years ago

Hi @fenos , I am not a 100% sure about this problem I am having but it may be because I am not doing something properly. Hopefully you can point me in the right direction.

The problem I am having is that I am getting stale data back after inserting a new document through a mutation and then attempting to query for it. Only after restarting the server do I receive these records i created earlier.

If i make a query though the graphiql interface (right after running the mutation) i can see the mutation result in the query (i.e new records show up).

I have created a mutation as follows:

const channelMutation = {
    createChannel: {
        type: channelType,
        args: {
            name: {
                description: 'The name of the channel.',
                type: new GraphQLNonNull(GraphQLString)
            },
            description: {
                description: 'The description of the channel.',
                type: new GraphQLNonNull(GraphQLString)
            },
            teamId: {
                description: 'The teamId the channel is associated with.',
                type: new GraphQLNonNull(GraphQLString)
            },
            createdBy: {
                description: 'The UUID of the user who created the channel.',
                type: new GraphQLNonNull(GraphQLString)
            }              
        },
        resolve: (obj, {name, description, teamId, createdBy}, ctx) => {       
            return createChannel(name, description, teamId, createdBy)
                .then((channel) => {
                    pubsub.publish(`channels.added.${teamId}`, channel) //ignore this .then() im using graphql subscriptions.
                    return channel
                })
        }
    }
}

createChannel is as follows:

import Channels from '../../models/channels'

export const createChannel = (name, description, teamId, createdBy) => {
    const newChannel = new Channels({
        name,
        description,
        teamId,
        createdBy,
    })
    return newChannel.save()
}

This is how i have defined the server.

import GT from '../utils/graphql-thinky'
router.get('/graphiql', graphiqlKoa({
    endpointURL: '/graphql'
}))
router.post('/graphql', graphqlKoa({
    schema: GraphQLSchema,
    context: {
        loaders: GT.getModelLoaders(),
    },
    debug: true,
}))

//for websocket subscription server same idea,
new SubscriptionServer(
    {
        subscriptionManager: createSubscriptionManager(GraphQLSchema),
        // the onSubscribe function is called for every new subscription
        // and we use it to set the GraphQL context for this subscription
        onSubscribe: (msg, params) => {
            console.log(GT.getModelLoaders())
            // console.log('ws onsubscribe', msg, params)
            return Object.assign({}, params, {
                context: {
                    loaders: GT.getModelLoaders(),
                },
            });
        },
    },
    websocketServer
);

Thanks!

fenos commented 7 years ago

@deep-c Hi, the problem of stale data is because you are not creating new instances of Dataloader for each request.

The function GT.getModelLoaders() returns instances of Dataloader, which they should be recreated for every request, otherwise they will be living forever.

To solve the problem use the following approach:

router.post('/graphql', graphqlKoa(request => ({
    schema: GraphQLSchema,
    context: {
        loaders: GT.getModelLoaders(),
    },
    debug: true,
})))
deep-c commented 7 years ago

@fenos Thanks so much! I completely skipped over that crucial detail. :)