Skip to content

Conversation

@ptomato
Copy link

@ptomatoptomato 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-botnodejs-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
@ptomatoptomato marked this pull request as draft June 27, 2020 02:51
@ptomato
Copy link
Author

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

Copy link
Member

@benjamingrbenjamingr 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

@addaleaxaddaleax 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! :)

@ptomato
Copy link
Author

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.

@ptomatoptomatoforce-pushed the 31971-fsreq-cancel branch from fa4e9e2 to 8ca9511CompareJuly 3, 2020 23:23
@ptomato
Copy link
Author

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.

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
@ptomatoptomatoforce-pushed the 31971-fsreq-cancel branch from 8ca9511 to 8236b52CompareAugust 4, 2020 01:31
@ptomato
Copy link
Author

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

@ptomatoptomato mentioned this pull request Nov 1, 2020
4 tasks
@ptomato
Copy link
Author

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.

@BridgeAR
Copy link
Member

I believe this is actually a better implementation than what we currently have, as far as I know.
I am nevertheless going to close it, since it would require a rebase and a new PR would probably be best for that to pick it up faster and land it.

Sign up for freeto 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 / srcIssues 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.

5 participants

@ptomato@BridgeAR@addaleax@benjamingr@nodejs-github-bot