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

Draft: Cancellation of FSReq #34080

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Conversation

ptomato
Copy link

@ptomato ptomato commented Jun 27, 2020

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

Draft for early feedback. This adds a cancel() method accessible from JS to FSReqBase which calls uv_cancel() via ReqWrap::Cancel() on the request. This would be a prerequisite for effectively integrating support for AbortController into the fs APIs (#31971).

Looking for feedback on the approach, if that seems sound then I will write tests and documentation.

To see how this is used in my experiments with cancellation, see https://github.com/nodejs/node/compare/master...ptomato:31971-abortcontroller?expand=1

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Jun 27, 2020
@ptomato ptomato marked this pull request as draft June 27, 2020 02:51
@ptomato
Copy link
Author

ptomato commented Jun 27, 2020

@addaleax, @jasnell, @Ethan-Arrowood, @benjamingr - I think I heard you volunteer to take a look at this during the collaborator summit 😄

Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

Generally looks fine :] Need a few days to review this on a computer with checked out code

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

Looks good so far! :)

src/node_file.cc Outdated Show resolved Hide resolved
@ptomato
Copy link
Author

ptomato commented Jul 3, 2020

Hmm, this is not as straightforward as these patches led me to believe. While writing tests for FSReqBase::Cancel() I discovered that the FSReq callback is not actually called with the AbortError that the code puts into FSReq::Reject(), but instead with libuv's ECANCELED error. So it seems like the AbortError bit is actually not doing anything. But on the other hand looking at https://github.com/nodejs/node/blob/master/src/req_wrap-inl.h#L47-L51 it's also not guaranteed that ReqWrap::Cancel() will actually call uv_cancel(), so I'm guessing in that case the request is rejected with the AbortError after all? I will need to think a bit more about what to do with this.

@ptomato ptomato force-pushed the 31971-fsreq-cancel branch from fa4e9e2 to 8ca9511 Compare July 3, 2020 23:23
@ptomato
Copy link
Author

ptomato commented Jul 3, 2020

I've taken a different approach now, so once again feedback on the approach is welcome. This stores a "cancelled" flag in FSReqBase, and if it is set to true, Resolve() will instead call Reject(), and Reject() will replace any original rejected error with the DOMException AbortError.

There are no tests for FSReqPromise as I'm not sure where that is actually used in lib/fs, it seems it's not possible to get its constructor from the internalBinding like I did with FSReqCallback in the tests.

ptomato added 2 commits August 3, 2020 18:13
GetDOMException() was a private function in node_messaging, but we would
like to use it to throw AbortErrors when cancelling something via an
AbortController. Move it into environment.cc to be in the same place as
GetPerContextExports(), and expose it internally in node_internals.h.

Refs: nodejs#31971
This adds a FSReqBase::Cancel() method which calls uv_cancel(). This
shows up in JS as a cancel() method on FSReqCallback and FSReqPromise.

Refs: nodejs#31971
@ptomato ptomato force-pushed the 31971-fsreq-cancel branch from 8ca9511 to 8236b52 Compare August 4, 2020 01:31
@ptomato
Copy link
Author

ptomato commented Aug 4, 2020

@addaleax, @jasnell, @Ethan-Arrowood, @benjamingr - I've rebased this on the latest, any comments on the new approach?

@ptomato
Copy link
Author

ptomato commented Nov 18, 2020

I probably won't be able to do more work on this until January, but if someone else would like to pick it up sooner, I'm happy to hand it off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants