apollo-client: Memory leak in client.query()

Activate pollInterval for a query.

Intended outcome:

Client can sit idle and do many polls without memory allocation increasing.

Actual outcome:

Allocated memory slowly climbs

How to reproduce the issue:

I am using react-apollo, with a simple query that fetches some counters using pollInterval:

const gqlCounters = gql`
query badgeCounters($accountId: Int!) {
  accountCounters(argId: $accountId) {
    nodes {
      bookingsPreliminary
      bookingsConfirmed
      bookingsForAccount
      unreadMessages
      eventSeq
}}}`;

let countersOptions = {
	skip: ( { accountId } ) => !accountId,
	options: ( { accountId } ) => {
		return { 
			variables: { accountId }, 
			pollInterval: 5000
		}
	},
	props: ( { ownProps, data: { loading, accountCounters, refetch, error } } ) => {
		let data= accountCounters && accountCounters.nodes[ 0 ];
		return ({
			counters: {
				loading,
				error,
				refetch,
				data
			}
		});
	}
};

I am using Chrome. If left idle for a few hours, the tab running the polling will slowly increase its memory allocation until Chrome finally crashes and becomes unresponsive.

Since I am using react-apollo, and the query is always returning the same result, my componentWillReceiveProps() code that handles the result of the query is never even called, so AFAICS this leak is happening inside Apollo itself.

I have tried to trace the leaked memory using the Google “Three Snapshots” technique, and see a lot of unreleased objects looking similar to this one:

image

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

I put the test app here (relevant files after creation with create-react-app):

https://gist.github.com/JesperWe/688ce0d78ad3a0aa675169d2aa558453

The server shouldn’t matter (I think you know which one I am using 😉…) just make it respond like above.

Yes. Well, as you can see this particular query does not even have an ID. I didn’t test the two properties individually, but when they are absent I can run forever without leaks, when addTypename and dataIdFromObject are there memory keeps growing even though the query response has no id (so dataIdFromObject should be returning null.