facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.36k stars 46.97k forks source link

Bug: server actions cannot be cancelled or given abort signals #28511

Open AaronFriel opened 8 months ago

AaronFriel commented 8 months ago

React version: 18.2.0

Steps To Reproduce

  1. As in #28510, create a server action that has some long-running delay, e.g.: to simulate a large language model call.
  2. There is no API on the client or server to trigger cancellation, or to detect or handle the client navigating away from the page.

Link to code example: https://codesandbox.io/p/devbox/next-14-0-3-forked-7q86s7?file=%2Fapp%2Factions.ts%3A4%2C18&workspaceId=958ee911-ec8f-4ca3-9ce1-668005ecaeb8

The current behavior

When a long-running request is fired, the server will complete it regardless of client behavior, e.g.: client hangup.

The expected behavior

An API for server actions to obtain a reference to an AbortController (or similar API) for the request, perhaps via async local context.

An API for clients to signal cancellation of a server action, perhaps via an additional return value on startTransition, perhaps as part of the transition APIs. If a transition is explicitly created, there should be a mechanism to cancel it.

Gaurav896260 commented 8 months ago

hey, To achieve the expected behavior, you would need to implement a mechanism on the server-side to handle this. One common approach is to use a unique token for each request. The client sends this token with each request, and if the client disconnects, it sends a cancellation request with the same token. The server then checks for cancellation requests with the same token before and during the processing of the request.

Screenshot 2024-03-10 152106

AaronFriel commented 8 months ago

I don't think that seems like a reasonable solution, as it relies upon:

Both of those seem pretty absurd, given that fetches can be aborted, the client can hang up the request. It should be possible to react to that.

C-mbai commented 5 months ago

+1 Please

schilffarth commented 2 months ago

.

Saran33 commented 2 months ago

It could be possible to set a cancellation token in redis for a requestID and continually poll redis within the server action to check if it's cancelled before parsing each message chunk. That way, it wouldn't matter where follow-up requests are routed, but as mentioned above, that seems like an absurd amount of complexity, not to mention overhead, for something so trivial with fetches