Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

stream_wrap: use uv_try_write where possible #6902

Closed
wants to merge 4 commits into from

Conversation

indutny
Copy link
Member

@indutny indutny commented Jan 17, 2014

Use uv_try_write for string and buffer writes, thus avoiding to do
allocations and copying in some of the cases.

/cc @tjfontaine @trevnorris

Use `uv_try_write` for string and buffer writes, thus avoiding to do
allocations and copying in some of the cases.
@@ -419,7 +419,6 @@ int uv__close(int fd) {
int rc;

assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */
assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */

Choose a reason for hiding this comment

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

merge issue? not sure why there's a change in deps/

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I'll remove it.

@trevnorris
Copy link

Will do a more through review. Though I have one general concern that's already an issue with the current streams API. If a user is writing out a bunch of small requests, and their waiting for the Stream API to tell them when to stop writing, there's the possibility of blocking the event loop for too long. If not indefinitely.

Where this is a problem is because in JS the callbacks are then called immediately. This can allow issues to occur when writing out large files that cause cause the ._buffers array on the stream to fill up and cause v8 to crash. Because the ._buffers array isn't emptied until after all writes are complete.

So, basically, there are issues with the Streams JS API that need to be resolved and this patch would make them more likely to happen.

Also, can you briefly explain when it's "immediately" written? Like, that it's just been passed off to the kernel to be written. Sorry, not familiar w/ how the system guts work.

Overall I like the idea. Adds complexity, but I see significant potential performance gains in key areas (e.g. intra-datacenter communication).

@indutny
Copy link
Member Author

indutny commented Jan 18, 2014

This patch would not change behavior of the streams, it just makes them skip allocation process if the write could be completed "immediately", and by immediately I mean that uv_try_write() will result in a write() call.

size_t data_size;
uv_buf_t buf;

bool try_write = storage_size + 15 <= sizeof(stack_storage) &&

Choose a reason for hiding this comment

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

we should be avoiding the use of magic numbers, that is to say -- can we use constant symbols instead? I know the 15 was there before this change.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, I haven't introduced it. And not going to fix it as part of this PR ;)

@indutny
Copy link
Member Author

indutny commented Jan 21, 2014

ping guys!

@trevnorris
Copy link

Throw in this:

diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index 3ae078c..39c139c 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -32,6 +32,7 @@
 #include "util.h"
 #include "util-inl.h"

+#include <string.h>  // memcpy()
 #include <stdlib.h>  // abort()
 #include <limits.h>  // INT_MAX

to get it to build

@indutny
Copy link
Member Author

indutny commented Jan 22, 2014

Pushed fix.

char* storage;
WriteWrap* req_wrap;
char* data;
char stack_storage[16384];

Choose a reason for hiding this comment

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

What's this magical 16384 from? Please place a comment why that number is significant. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

16 kb, I'll add it.

@trevnorris
Copy link

@indutny did my thing. ping me back. :)

@indutny
Copy link
Member Author

indutny commented Jan 22, 2014

@trevnorris all fixed, I think?

@indutny
Copy link
Member Author

indutny commented Jan 22, 2014

Needs to be landed after joyent/libuv#1086

@trevnorris
Copy link

ok. think I'm cool with this.

@indutny
Copy link
Member Author

indutny commented Jan 23, 2014

Ok, I have another fix instead that one.

@indutny
Copy link
Member Author

indutny commented Jan 23, 2014

This one: #6946

@indutny
Copy link
Member Author

indutny commented Jan 23, 2014

@trevnorris LGTY?

@trevnorris
Copy link

Logic seems good, but posterity be warned that I don't understand the inner workings of uv_try_write().

@indutny LGTM.

@indutny
Copy link
Member Author

indutny commented Jan 24, 2014

@tjfontaine your turn, please ;)

req.cb = cb;
} else {
if (!req.async)
timers._unrefActive(this);

Choose a reason for hiding this comment

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

Why do we need to set the timer here vs L620?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is not required, I guess it is a mistake...

@tjfontaine
Copy link

I am basically +1 on this, though I would appreciate some comment blocks on the interfaces such that I don't have to think about the semantics in detail every time I approach it

@indutny
Copy link
Member Author

indutny commented Jan 28, 2014

Thank you, landed in 9836a4e

@indutny indutny closed this Jan 28, 2014
@indutny indutny deleted the feature/try-write branch January 28, 2014 23:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants