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

Propagate the abort signal to allow for automatic query cancellation #9612

Merged
merged 13 commits into from
Feb 12, 2024

Conversation

slax57
Copy link
Contributor

@slax57 slax57 commented Jan 24, 2024

TanStack Query provides each query function with an AbortSignal instance. When a query becomes out-of-date or inactive, this signal will become aborted.

This PR takes advantage of this, by propagating the abort signal to the dataProvider and authProvider, to allow for automatically aborting the request when the query is canceled.

Todo

  • Add the abort signal to the parameters of all dataProvider and authProvider methods
  • Update the tests
  • Update our data providers (simple rest, graphql simple, ...) to support this feature
  • Update the “writing a data provider” doc to mention it
  • Complete the upgrade guide

How to test

You can see query cancellation in action in

  • the tutorial example for ra-data-json-server
  • the e-commerce demo in GraphQL mode for ra-data-graphql (<- you will need to comment out the fetchMock part in examples/demo/src/fakeServer/graphql.ts and run a 'real' graphql server, e.g. with json-graphql-server)

You can use the browser's DevTools to

  • disable network cache
  • throttle the requests, e.g. by selecting 'Slow 3G'

With that in place, you can for instance click multiple times on the header of a Datagrid to toggle sorting in ASC or DESC order, and see in the Network tab that all requests except the last one are canceled.

2024-01-26_11-27

How to update your DataProvider to benefit from this feature

DataProvider query functions (getOne, getList, getMany and getManyReference) are now provided with an additional signal parameter. This parameter is an AbortSignal that can be used to abort the request when the query is canceled (e.g. when it becomes out-of-date or inactive).

The following dataProviders, provided by react-admin, have already been updated to support this new parameter:

  • ra-data-json-server
  • ra-data-simple-rest
  • ra-data-graphql

This feature is optional, so you can still use any other dataProvider, even if it doesn't yet support the signal parameter.

If you wish to update your own dataProvider to support this new parameter, you can take inspiration from how we updated the ra-data-simple-rest dataProvider:

// In packages/ra-data-simple-rest/src/index.ts
import { fetchUtils, DataProvider } from 'react-admin';

export default (
    apiUrl: string,
    httpClient = fetchUtils.fetchJson,
    countHeader: string = 'Content-Range'
): DataProvider => ({
    getOne: (resource, params) =>
-       httpClient(`${apiUrl}/${resource}/${params.id}`).then(({ json }) => ({
+       httpClient(`${apiUrl}/${resource}/${params.id}`, {
+           signal: params?.signal,
+       }).then(({ json }) => ({
            data: json,
        })),

    /* ... other dataProvider methods ... */
});

You can find more example implementations in the Query Cancellation guide.

@slax57 slax57 added the WIP Work In Progress label Jan 24, 2024
@djhi
Copy link
Collaborator

djhi commented Jan 29, 2024

When running the ecommerce demo and navigating quickly between pages, we now have errors about aborted operations in the console.

DOMException: The operation was aborted.

Those occur in the useDataProvider file.

I wonder whether we should detect those errors and avoid the log

Copy link
Member

@fzaninotto fzaninotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason I can't reproduce the query cancellation in the tutorial example on my machine :(

docs/Upgrade.md Outdated Show resolved Hide resolved
packages/ra-core/src/auth/useAuthState.ts Show resolved Hide resolved
packages/ra-core/src/types.ts Show resolved Hide resolved
packages/ra-core/src/form/useUnique.spec.tsx Show resolved Hide resolved
cypress/e2e/edit.cy.js Show resolved Hide resolved
docs/Upgrade.md Show resolved Hide resolved
packages/ra-core/src/auth/useAuthState.ts Show resolved Hide resolved
packages/ra-core/src/types.ts Show resolved Hide resolved
docs/Upgrade.md Outdated Show resolved Hide resolved
packages/ra-core/src/form/useUnique.spec.tsx Show resolved Hide resolved
@slax57 slax57 added WIP Work In Progress and removed RFR Ready For Review labels Feb 12, 2024
@slax57
Copy link
Contributor Author

slax57 commented Feb 12, 2024

Back to WIP: @fzaninotto and I discovered a bug where the users are not loaded correctly in the tutorial project.

2024-02-12_10-36

Error: DOMException: signal is aborted without reason

@slax57
Copy link
Contributor Author

slax57 commented Feb 12, 2024

Only thing left to do is to decide what to do with this DOMException: The operation was aborted error...

@slax57
Copy link
Contributor Author

slax57 commented Feb 12, 2024

Only thing left to do is to decide what to do with this DOMException: The operation was aborted error...

Fixed! Back to RFR

@fzaninotto fzaninotto merged commit 4b969c4 into next Feb 12, 2024
12 checks passed
@fzaninotto fzaninotto deleted the auto-query-cancellation branch February 12, 2024 14:47
@fzaninotto fzaninotto added this to the 5.0.0 milestone Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants