Initial corking and copy strategy, large and small sends
This commit is contained in:
@@ -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
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user