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

src: introduce PullAll method to speed up blob.text/arrayBuffer #49873

Closed
wants to merge 168 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
33e2913
src: introduce PullAll method to speed up blob.text/arrayBuffer
debadree25 Sep 26, 2023
eb086f2
fixup! linting
debadree25 Sep 26, 2023
6975d04
fixup! get everything working
debadree25 Sep 27, 2023
0f22ac7
fixup! no return
debadree25 Sep 27, 2023
d6cd738
fixup! use use emplace and update for
debadree25 Sep 27, 2023
7de4169
tools: support updating @reporters/github manually
MoLow Sep 26, 2023
5eb1cd2
url: improve invalid url performance
anonrig Sep 26, 2023
97c63a6
stream: use bitmap in writable state
rluvaton Sep 26, 2023
c496080
test: deflake test-runner-output
MoLow Sep 26, 2023
88488c3
perf_hooks: reduce overhead of new performance_entries
H4ad Sep 27, 2023
8bc06eb
fs: improve error performance for `unlinkSync`
CanadaHonk Sep 27, 2023
554bc6e
fs: replace `SetMethodNoSideEffect` in node_file
CanadaHonk Sep 27, 2023
da89771
test: add os setPriority, getPriority test coverage
waelsy123 Sep 27, 2023
6575fac
deps: V8: cherry-pick 8ec2651fbdd8
abmusse Sep 27, 2023
9e04f2c
errors: improve performance of instantiation
Uzlopak Sep 28, 2023
c954b18
lib,test: do not hardcode Buffer.kMaxLength
targos Sep 28, 2023
cb4476b
lib: add WebSocket client
KhafraDev Sep 28, 2023
5990034
tools: update github_reporter to 1.5.3
nodejs-github-bot Sep 28, 2023
41f56e9
tools: use osx notarytool for future releases
UlisesGascon Jul 8, 2023
c0826c7
doc: add navigation ARIA landmark to doc ToC
Trott Sep 26, 2023
af6db5c
doc: add main ARIA landmark to API docs
Trott Sep 26, 2023
92295eb
tools: add navigation ARIA landmark to generated API ToC
Trott Sep 26, 2023
4d48632
meta: update website team with new name
Trott Sep 26, 2023
2eb20e5
2023-09-28, Version 20.8.0 (Current)
ruyadorno Sep 28, 2023
efb7614
esm: --experimental-default-type flag to flip module defaults
GeoffreyBooth Sep 29, 2023
a74d043
esm: fix cache collision on JSON files using file: URL
aduh95 Sep 29, 2023
95b34c3
fs: adjust `position` validation in reading methods
LiviaMedeiros Sep 29, 2023
b36d25f
events: validate options of `on` and `once`
deokjinkim Sep 29, 2023
9f848d2
crypto: return clear errors when loading invalid PFX data
pimterry Sep 29, 2023
b3feb52
errors: improve formatList in errors.js
Uzlopak Sep 29, 2023
c18b114
src: move const variable in `node_file.h` to `node_file.cc`
Sep 29, 2023
0025722
test_runner: replace spurious if with else
cjihrig Sep 29, 2023
aea6fa3
lib: update params in jsdoc for `HTTPRequestOptions`
Sep 29, 2023
9c5d249
doc: document dangerous symlink behavior
tniessen Sep 29, 2023
f5255f9
lib: fix `primordials` typings
SamVerschueren Sep 29, 2023
c6e16b1
zlib: fix discovery of cpu-features.h for android
MatteoBax Sep 29, 2023
1fe6ca2
test: deflake test-perf-hooks.js
joyeecheung Sep 27, 2023
8871e94
doc: update CHANGELOG_V20 about vm fixes
joyeecheung Sep 29, 2023
24e646b
stream: writable state bitmap
ronag Sep 29, 2023
de0939c
test: disambiguate AIX and IBM i
richardlau Sep 28, 2023
0751057
build: fix IBM i build with Python 3.9
richardlau May 18, 2023
692fa20
deps: update uvwasi to 0.0.19
nodejs-github-bot Sep 27, 2023
a1da235
wasi: updates required for latest uvwasi version
mhdawson Sep 27, 2023
3ae48d7
fs: throw errors from sync branches instead of separate implementations
joyeecheung Sep 30, 2023
8762899
inspector: simplify dispatchProtocolMessage
lemire Sep 30, 2023
2f830af
module: move helpers out of cjs loader
GeoffreyBooth Sep 30, 2023
b4c1eb5
deps: update ada to 2.6.3
nodejs-github-bot Aug 27, 2023
b8dc496
deps: update ada to 2.6.5
nodejs-github-bot Sep 3, 2023
8062d42
deps: update ada to 2.6.7
nodejs-github-bot Sep 10, 2023
7897fbe
deps: update ada to 2.6.8
nodejs-github-bot Sep 19, 2023
3a5172e
deps: update ada to 2.6.9
nodejs-github-bot Sep 29, 2023
b065bfa
Revert "test: mark test-runner-output as flaky"
lpinca Sep 30, 2023
ba272e1
test: update skip for moved `test-wasm-web-api`
richardlau Sep 30, 2023
f0bb380
lib: make fetch sync and return a Promise
KhafraDev Sep 30, 2023
8dc9233
src: use exact return value for `uv_os_getenv`
anonrig Sep 30, 2023
b19350e
errors: improve performance of determine-specific-type
Uzlopak Sep 30, 2023
e9fdd1c
perf_hooks: reduce overhead of new resource timings
H4ad Sep 30, 2023
f18320c
tls: use validateFunction for `options.checkServerIdentity`
deokjinkim Sep 30, 2023
739f0ab
esm: improve JSDoc annotation of internal functions
aduh95 Oct 1, 2023
5415139
doc: updated building docs for windows
ovflowd Oct 1, 2023
890d831
esm: improve `getFormatOfExtensionlessFile` speed
anonrig Oct 1, 2023
b2d0b29
doc: update link to Abstract Modules Records spec
Trott Oct 1, 2023
b20e7c8
stream: avoid tick in writable hot path
ronag Oct 1, 2023
8ef0c1c
doc: update Collaborator pronouns
bnb Oct 1, 2023
cb8e195
deps: fix call to undeclared functions 'ntohl' and 'htons'
MatteoBax Oct 2, 2023
9163bba
lib: reduce overhead of validateObject
H4ad Oct 2, 2023
cf66f7d
deps: update ada to 2.6.10
nodejs-github-bot Oct 3, 2023
ddaa3f6
esm: unflag extensionless javascript and wasm in module scope
GeoffreyBooth Sep 30, 2023
e006c7a
doc: reserve 119 for Electron 28
dsanders11 Oct 3, 2023
637d6c5
deps: update googletest to e47544a
nodejs-github-bot Oct 3, 2023
0158bb8
tools: update lint-md-dependencies
nodejs-github-bot Oct 3, 2023
385cfa2
node-api: run finalizers directly from GC
vmoroz Jun 23, 2023
49c7e45
tools: update eslint to 8.50.0
nodejs-github-bot Oct 3, 2023
98806b1
test_runner: add test location for FileTests
cjihrig Oct 3, 2023
4b7fc22
fs: improve error performance for `fdatasyncSync`
Oct 4, 2023
65128b7
perf_hooks: reducing overhead of performance observer entry list
H4ad Oct 4, 2023
bc25ec1
benchmark: added new benchmarks for blob
H4ad Sep 20, 2023
f7ca69c
lib: faster internal createBlob
H4ad Sep 20, 2023
1f30134
benchmark: improved config for blob,file benchmark
H4ad Sep 22, 2023
e290ec0
tls: ciphers allow bang syntax
atlowChemi Oct 4, 2023
d1b03e0
src: name scoped lock
VoltrexKeyva Oct 4, 2023
c1ed261
stream: optimize Writable
ronag Oct 4, 2023
9edaaf7
stream: avoid unnecessary drain for sync stream
ronag Oct 4, 2023
b665c95
fs: add flush option to writeFile() functions
cjihrig Oct 4, 2023
3bbb759
tls: handle cases where the raw socket is destroyed
lpinca Oct 4, 2023
0475027
wasi: fix up wasi tests for ibmi
mhdawson Oct 4, 2023
fd6d362
meta: bump actions/checkout from 3.6.0 to 4.1.0
dependabot[bot] Oct 4, 2023
fa61f24
meta: bump github/codeql-action from 2.21.5 to 2.21.9
dependabot[bot] Oct 4, 2023
bce3251
meta: bump actions/cache from 3.3.1 to 3.3.2
dependabot[bot] Oct 4, 2023
3a105fe
meta: bump actions/upload-artifact from 3.1.2 to 3.1.3
dependabot[bot] Oct 4, 2023
ead31aa
src: set port in node_options to uint16_t
anonrig Aug 13, 2023
6761dc2
src: fix TLSWrap lifetime bug in ALPN callback
bnoordhuis Oct 4, 2023
8650351
vm: use default HDO when importModuleDynamically is not set
joyeecheung Oct 5, 2023
7665ea7
perf_hooks: reduce overhead of new user timings
H4ad Oct 5, 2023
3941379
node-api: update headers for better wasm support
toyobayashi Oct 5, 2023
672f793
esm: bypass CommonJS loader under --default-type
GeoffreyBooth Oct 5, 2023
e7a7779
stream: lazy allocate back pressure buffer
ronag Oct 5, 2023
c7a26dd
tools: remove genv8constants.py
bnoordhuis Oct 5, 2023
b8b8724
crypto: account for disabled SharedArrayBuffer
codebytere Oct 6, 2023
1656c5b
tls: use `validateNumber` for `options.minDHSize`
deokjinkim Oct 6, 2023
fe7c701
http: refactor to make servername option normalization testable
pd4d10 Oct 6, 2023
dfa47f0
doc: clarify explaination text on how to run the example
anshulshacks Oct 6, 2023
cb854ac
test: change forEach to for...of
tifflastimosa Oct 6, 2023
98813e7
test: replace forEach() in test-net-perf_hooks with for of
narcisacodreanu Oct 6, 2023
5585de4
lib: fix compileFunction throws range error for negative numbers
MrJithil Oct 6, 2023
9e155e8
test,crypto: update WebCryptoAPI WPT
panva Oct 6, 2023
3cc6e5a
test_runner: disallow array in `run` options
rluvaton Oct 6, 2023
8a6db3f
lib: let deps require `node` prefixed modules
KhafraDev Oct 6, 2023
2b77d58
test: replace forEach with for..of in test-http-url
niyashiyas Sep 24, 2023
cf393e5
test: replace forEach with for..of in test-process-env
niyashiyas Oct 7, 2023
57903d8
deps: update undici to 5.25.4
nodejs-github-bot Oct 8, 2023
cad9376
doc: use precise terminology in test runner
benjamingr Oct 8, 2023
4853671
doc: use precise promise terminology in fs
benjamingr Oct 8, 2023
0be708e
src: throw DOMException on cloning non-serializable objects
legendecas Oct 8, 2023
063f689
util: lazy parse mime parameters
Uzlopak Oct 8, 2023
78908e9
vm: freeze `dependencySpecifiers` array
aduh95 Oct 8, 2023
5346e73
tools: update eslint to 8.51.0
nodejs-github-bot Oct 8, 2023
1ffbb10
test_runner, cli: add --test-concurrency flag
cjihrig Oct 1, 2023
e9e025a
doc: add command to get patch minors and majors
RafaelGSS Oct 8, 2023
36929cb
doc: move permission model to Active Development
RafaelGSS Oct 8, 2023
86887f1
doc: mention files read before env setup
RafaelGSS Oct 8, 2023
135b8f0
src: generate default snapshot with --predictable
joyeecheung Oct 9, 2023
231e33e
test: replace forEach with for..of in test-parse-args.mjs
niyashiyas Oct 9, 2023
acbcde3
crypto: use X509_ALGOR accessors instead of reaching into X509_ALGOR
davidben Oct 9, 2023
1b11447
build: drop support for Visual Studio 2019
targos Oct 9, 2023
0912b61
deps: update googletest to 2dd1c13
nodejs-github-bot Oct 10, 2023
3d4d114
tools: update lint-md-dependencies
nodejs-github-bot Oct 10, 2023
2106839
deps: update zlib to 1.2.13.1-motley-fef5869
nodejs-github-bot Oct 10, 2023
88675bb
deps: update V8 to 11.8.172.13
targos Oct 5, 2023
5eb529e
build: reset embedder string to "-node.0"
targos Oct 5, 2023
db6a0e2
src: update NODE_MODULE_VERSION to 120
targos Sep 13, 2023
3e717ec
deps: always define V8_EXPORT_PRIVATE as no-op
targos Sep 21, 2022
fc00596
deps: silence irrelevant V8 warning
targos Jun 21, 2022
fd233ea
deps: disable V8 concurrent sparkplug compilation
targos Apr 6, 2023
b8c972b
deps: avoid compilation error with ASan
targos Jul 31, 2023
e87cbf5
deps: remove usage of a C++20 feature from V8
targos Aug 10, 2023
42f1e3a
deps: patch V8 to avoid duplicated zlib symbol
targos Sep 16, 2023
fe3a1e3
deps: V8: cherry-pick 1a3ecc2483b2
targos Sep 13, 2023
5a743ff
deps: V8: cherry-pick 93b1a74cbc9b
targos Sep 15, 2023
920e206
deps: V8: cherry-pick b5b5d6c31bb0
targos Sep 22, 2023
30200cb
deps: V8: cherry-pick de9a5de2274f
targos Sep 26, 2023
d4924e4
deps: V8: cherry-pick 89b3702c92b0
targos Sep 26, 2023
cd7da8c
deps: V8: cherry-pick 8ec2651fbdd8
targos Oct 5, 2023
cbcdb50
deps: bump minimum ICU version to 73
targos Jul 7, 2023
d48ba77
tools: update V8 gypfiles for 11.4
targos Mar 31, 2023
edce6ae
tools: update V8 gypfiles for 11.5
targos Apr 30, 2023
410e6b8
tools: update V8 gypfiles for 11.6
targos Jun 12, 2023
cc4505f
tools: update V8 gypfiles for 11.7
targos Jul 7, 2023
eda59e7
tools: update V8 gypfiles for 11.8
targos Aug 10, 2023
a95b2d2
tools: add new V8 headers to distribution
targos Mar 31, 2023
a7a5db3
lib: update usage of always on Atomics API
targos Apr 16, 2023
7b537c7
test: adapt debugger tests to V8 11.4
pfaffe Mar 17, 2023
87632af
test: update flag to disable SharedArrayBuffer
targos Apr 20, 2023
cb454a9
test: adapt test-fs-write to V8 internal changes
targos May 6, 2023
735a80d
test: adapt REPL test to V8 changes
targos Jul 7, 2023
8b4a14d
test: skip test-tick-processor-arguments on SmartOS
targos Oct 5, 2023
cd32d73
test: skip v8-updates/test-linux-perf
targos Oct 7, 2023
b27b3a8
src: avoid making JSTransferable wrapper object weak
legendecas Oct 10, 2023
4eda24d
2023-10-10, Version 18.18.1 'Hydrogen' (LTS)
richardlau Oct 6, 2023
0345207
doc: fix description of `fs.readdir` `recursive` option
Oct 10, 2023
e41fa7f
deps: update simdutf to 3.2.18
nodejs-github-bot Oct 10, 2023
418416a
fs: improve error performance for `ftruncateSync`
andremralves Oct 10, 2023
54c1138
deps: update corepack to 0.21.0
nodejs-github-bot Oct 11, 2023
d1878d3
fs: add flush option to createWriteStream()
cjihrig Oct 11, 2023
d8ddf86
doc: move danielleadams to TSC non-voting member
danielleadams Oct 11, 2023
feae47a
deps: update nghttp2 to 1.57.0
jasnell Oct 11, 2023
128aae4
test_runner,test: fix flaky test-runner-cli-concurrency.js
cjihrig Oct 12, 2023
d75f4f9
fs: improve error performance of writevSync
IlyasShabi Oct 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 11 additions & 23 deletions lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const {
const {
createBlob: _createBlob,
createBlobFromFilePath: _createBlobFromFilePath,
concat,
getDataObject,
} = internalBinding('blob');

Expand Down Expand Up @@ -274,28 +273,17 @@ class Blob {

const { promise, resolve, reject } = createDeferredPromise();
const reader = this[kHandle].getReader();
const buffers = [];
const readNext = () => {
reader.pull((status, buffer) => {
if (status === 0) {
// EOS, concat & resolve
// buffer should be undefined here
resolve(concat(buffers));
return;
} else if (status < 0) {
// The read could fail for many different reasons when reading
// from a non-memory resident blob part (e.g. file-backed blob).
// The error details the system error code.
const error = lazyDOMException('The blob could not be read', 'NotReadableError');
reject(error);
return;
}
if (buffer !== undefined)
buffers.push(buffer);
queueMicrotask(() => readNext());
});
};
readNext();
reader.pullAll((status, buffer) => {
if (status === 0) {
resolve(buffer);
} else if (status < 0) {
// The read could fail for many different reasons when reading
// from a non-memory resident blob part (e.g. file-backed blob).
// The error details the system error code.
const error = lazyDOMException('The blob could not be read', 'NotReadableError');
reject(error);
Copy link
Member

Choose a reason for hiding this comment

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

If you pass resolve and reject methods to pullAll function, we don't even need to return anything and just handle it on C++ side. It might provide a performance boost. This would also reduce calling and mutating the callback function.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea!

}
});
return promise;
}

Expand Down
90 changes: 90 additions & 0 deletions src/node_blob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ Local<FunctionTemplate> Blob::Reader::GetConstructorTemplate(Environment* env) {
BaseObject::kInternalFieldCount);
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "BlobReader"));
SetProtoMethod(env->isolate(), tmpl, "pull", Pull);
SetProtoMethod(env->isolate(), tmpl, "pullAll", PullAll);
Copy link
Member

Choose a reason for hiding this comment

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

Can you also update typescript typings for blob?

Copy link
Member Author

Choose a reason for hiding this comment

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

Updating

env->set_blob_reader_constructor_template(tmpl);
}
return tmpl;
Expand Down Expand Up @@ -379,6 +380,94 @@ void Blob::Reader::Pull(const FunctionCallbackInfo<Value>& args) {
std::move(next), node::bob::OPTIONS_END, nullptr, 0));
}

void Blob::Reader::PullAll(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Blob::Reader* reader;
ASSIGN_OR_RETURN_UNWRAP(&reader, args.Holder());

CHECK(args[0]->IsFunction());
Local<Function> fn = args[0].As<Function>();
CHECK(!fn->IsConstructor());

if (reader->eos_) {
Local<Value> arg = Int32::New(env->isolate(), bob::STATUS_EOS);
reader->MakeCallback(fn, 1, &arg);
return args.GetReturnValue().Set(bob::STATUS_EOS);
debadree25 marked this conversation as resolved.
Show resolved Hide resolved
}

struct View {
std::shared_ptr<BackingStore> store;
size_t length;
size_t offset = 0;
};

struct Impl {
Copy link
Member

Choose a reason for hiding this comment

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

Can we use a little more descriptive struct names?

BaseObjectPtr<Blob::Reader> reader;
Global<Function> callback;
Environment* env;
size_t total = 0;
std::vector<View> views;
int status = 1;
};

Impl* impl = new Impl();
impl->reader = BaseObjectPtr<Blob::Reader>(reader);
impl->callback.Reset(env->isolate(), fn);
impl->env = env;

auto next = [impl](int status,
const DataQueue::Vec* vecs,
size_t count,
bob::Done doneCb) mutable {
Environment* env = impl->env;
if (status == bob::STATUS_EOS) impl->reader->eos_ = true;

if (count > 0) {
// Copy the returns vectors into a single ArrayBuffer.
size_t total = 0;
for (size_t n = 0; n < count; n++) total += vecs[n].len;

std::shared_ptr<BackingStore> store =
v8::ArrayBuffer::NewBackingStore(env->isolate(), total);
auto ptr = static_cast<uint8_t*>(store->Data());
for (size_t n = 0; n < count; n++) {
std::copy(vecs[n].base, vecs[n].base + vecs[n].len, ptr);
ptr += vecs[n].len;
}
// Since we copied the data buffers, signal that we're done with them.
std::move(doneCb)(0);
Copy link
Member

Choose a reason for hiding this comment

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

I personnally do not understand why there is a std::move... If it is correct, I recommend adding a comment to explain it.

impl->views.push_back(View{store, total});
debadree25 marked this conversation as resolved.
Show resolved Hide resolved
impl->total += total;
}

impl->status = status;
return;
};

while (impl->status > 0) {
impl->reader->inner_->Pull(next, node::bob::OPTIONS_END, nullptr, 0);
debadree25 marked this conversation as resolved.
Show resolved Hide resolved
};

std::shared_ptr<BackingStore> store =
ArrayBuffer::NewBackingStore(env->isolate(), impl->total);
auto ptr = static_cast<uint8_t*>(store->Data());
for (size_t n = 0; n < impl->views.size(); n++) {
debadree25 marked this conversation as resolved.
Show resolved Hide resolved
uint8_t* from = static_cast<uint8_t*>(impl->views[n].store->Data()) +
impl->views[n].offset;
std::copy(from, from + impl->views[n].length, ptr);
ptr += impl->views[n].length;
}

Local<Value> argv[2] = {
Int32::New(env->isolate(), impl->status),
ArrayBuffer::New(env->isolate(), store),
};

impl->reader->MakeCallback(fn, arraysize(argv), argv);
auto dropMe = std::unique_ptr<Impl>(impl);
args.GetReturnValue().Set(impl->status);
}

BaseObjectPtr<BaseObject>
Blob::BlobTransferData::Deserialize(
Environment* env,
Expand Down Expand Up @@ -560,6 +649,7 @@ void Blob::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(Blob::GetDataObject);
registry->Register(Blob::RevokeObjectURL);
registry->Register(Blob::Reader::Pull);
registry->Register(Blob::Reader::PullAll);
registry->Register(Concat);
registry->Register(BlobFromFilePath);
}
Expand Down
1 change: 1 addition & 0 deletions src/node_blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Blob : public BaseObject {
static BaseObjectPtr<Reader> Create(Environment* env,
BaseObjectPtr<Blob> blob);
static void Pull(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PullAll(const v8::FunctionCallbackInfo<v8::Value>& args);

explicit Reader(Environment* env,
v8::Local<v8::Object> obj,
Expand Down