Initial corking and copy strategy, large and small sends

This commit is contained in:
Alex Hultman
2018-06-25 00:14:22 +02:00
parent ccff240619
commit f206a0c931
2 changed files with 34 additions and 24 deletions
+5 -6
View File
@@ -1,15 +1,14 @@
#include <string> #include "uWS.h"
std::string buffer; std::string buffer;
#include "uWS.h"
//#define USE_SSL //#define USE_SSL
int main() { int main() {
buffer = "HTTP/1.1 200 OK\r\nContent-Length: 52428800\r\n\r\n"; buffer = "Hello world!";
buffer.resize(52428800 + buffer.length());
//buffer.resize(512);
//uWS::init(); //uWS::init();
//uWS::Loop loop(); //uWS::Loop loop();
@@ -25,7 +24,7 @@ int main() {
app.onGet("/", [](auto *s, auto *req, auto *args) { app.onGet("/", [](auto *s, auto *req, auto *args) {
s->/*writeStatus("200 OK")->*/write([](int offset) { s->writeStatus("200 OK")->write([](int offset) {
return std::string_view(buffer.data() + offset, buffer.length() - offset); return std::string_view(buffer.data() + offset, buffer.length() - offset);
}, buffer.length()); }, buffer.length());
+29 -18
View File
@@ -62,7 +62,7 @@ struct HttpSocket {
} }
// never rely on this one! // never rely on this one!
void writeToCorkBufferAndReset(const char *src, int length, int contentLength) { int writeToCorkBufferAndReset(const char *src, int length, int contentLength) {
uWS::Loop::Data *loopData = (uWS::Loop::Data *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); uWS::Loop::Data *loopData = (uWS::Loop::Data *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16); memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16);
@@ -77,13 +77,17 @@ struct HttpSocket {
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length); memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
loopData->corkOffset += length; loopData->corkOffset += length;
int written;
if constexpr(SSL) { if constexpr(SSL) {
us_ssl_socket_write((us_ssl_socket *) this, loopData->corkBuffer, loopData->corkOffset); written = us_ssl_socket_write((us_ssl_socket *) this, loopData->corkBuffer, loopData->corkOffset);
} else { } else {
us_socket_write((us_socket *) this, loopData->corkBuffer, loopData->corkOffset, 0); written = us_socket_write((us_socket *) this, loopData->corkBuffer, loopData->corkOffset, 0);
} }
loopData->corkOffset = 0; loopData->corkOffset = 0;
return written;
} }
HttpSocket *writeStatus(std::string_view status) { HttpSocket *writeStatus(std::string_view status) {
@@ -103,30 +107,37 @@ struct HttpSocket {
void end(std::string_view data) { void end(std::string_view data) {
// end should not explicitly flush the cork buffer! delay to when done with all http data! // end should not explicitly flush the cork buffer! delay to when done with all http data!
writeToCorkBufferAndReset(data.data(), data.length()); writeToCorkBufferAndReset(data.data(), data.length(), data.length());
} }
// stream out (todo: fix up large sends and benchmark it again) // stream out (todo: fix up large sends and benchmark it again)
void write(std::function<std::string_view(int)> cb, int length) { void write(std::function<std::string_view(int)> cb, int length) {
// just assume this went fine
Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
//httpData->offset = 0;//uWS::Loop::MAX_COPY_DISTANCE;
// now we start streaming as much as possible in each call!
std::string_view chunk = cb(0); std::string_view chunk = cb(0);
// write that off! if (length < uWS::Loop::MAX_COPY_DISTANCE) {
if constexpr (SSL) { // what if the streamer cannot return any data?
// then it should return something to pause write, and then start it again
// basically we need throttling
writeToCorkBufferAndReset(chunk.data(), chunk.length(), length);
} else { } else {
httpData->offset = us_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0); // basically finish off the header section and send it as separate syscall (we do not copy anthing in this strategy)
} writeToCorkBufferAndReset(nullptr, 0, length);
// if offset is at the end, we are done // just assume this went fine
if (httpData->offset < length) { Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
httpData->outStream = cb;
// write that off!
if constexpr (SSL) {
} else {
httpData->offset = us_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0);
}
// if offset is at the end, we are done
if (httpData->offset < length) {
httpData->outStream = cb;
}
} }
} }