mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
server cleanup, fix logic error in early promise resolution
This commit is contained in:
parent
cf9bee07db
commit
f923762c7e
@ -69,6 +69,7 @@ struct MonitorScope {
|
||||
// registerClient and deregisterClient
|
||||
struct LaminarClient {
|
||||
virtual void sendMessage(std::string payload) = 0;
|
||||
virtual void close() = 0;
|
||||
MonitorScope scope;
|
||||
};
|
||||
|
||||
|
@ -174,6 +174,7 @@ public:
|
||||
std::string content;
|
||||
if(laminar.getArtefact(file, content)) {
|
||||
c->set_status(websocketpp::http::status_code::ok);
|
||||
c->append_header("Content-Transfer-Encoding", "binary");
|
||||
c->set_body(content);
|
||||
} else {
|
||||
c->set_status(websocketpp::http::status_code::not_found);
|
||||
@ -181,11 +182,14 @@ public:
|
||||
} else if(resources.handleRequest(resource, &start, &end)) {
|
||||
c->set_status(websocketpp::http::status_code::ok);
|
||||
c->append_header("Content-Encoding", "gzip");
|
||||
c->set_body(std::string(start, end));
|
||||
c->append_header("Content-Transfer-Encoding", "binary");
|
||||
std::string response(start,end);
|
||||
c->set_body(response);
|
||||
} else {
|
||||
// 404
|
||||
c->set_status(websocketpp::http::status_code::not_found);
|
||||
}
|
||||
c->lc->close();
|
||||
});
|
||||
|
||||
// Handle new websocket connection. Parse the URL to determine
|
||||
@ -223,7 +227,9 @@ public:
|
||||
});
|
||||
|
||||
wss.set_close_handler([this](websocketpp::connection_hdl hdl){
|
||||
laminar.deregisterClient(wss.get_con_from_hdl(hdl)->lc);
|
||||
websocket::connection_ptr c = wss.get_con_from_hdl(hdl);
|
||||
laminar.deregisterClient(c->lc);
|
||||
c->lc->close();
|
||||
});
|
||||
}
|
||||
|
||||
@ -266,7 +272,8 @@ struct Server::WebsocketConnection : public LaminarClient, public std::streambuf
|
||||
stream(kj::mv(stream)),
|
||||
out(this),
|
||||
cn(http.newConnection(this)),
|
||||
writePaf(kj::newPromiseAndFulfiller<void>())
|
||||
writePaf(kj::newPromiseAndFulfiller<void>()),
|
||||
closeOnComplete(false)
|
||||
{
|
||||
cn->register_ostream(&out);
|
||||
cn->start();
|
||||
@ -278,7 +285,7 @@ struct Server::WebsocketConnection : public LaminarClient, public std::streambuf
|
||||
}
|
||||
|
||||
kj::Promise<void> pend() {
|
||||
return stream->tryRead(ibuf, 1, 1024).then([this](size_t sz){
|
||||
return stream->tryRead(ibuf, 1, sizeof(ibuf)).then([this](size_t sz){
|
||||
cn->read_all(ibuf, sz);
|
||||
if(sz == 0 || cn->get_state() == websocketpp::session::state::closed) {
|
||||
cn->eof();
|
||||
@ -298,9 +305,9 @@ struct Server::WebsocketConnection : public LaminarClient, public std::streambuf
|
||||
if(payload.empty()) {
|
||||
return kj::Promise<void>(kj::READY_NOW);
|
||||
} else {
|
||||
return stream->write(payload.data(), payload.length()).then([this]{
|
||||
return writeTask();
|
||||
});
|
||||
return stream->write(payload.data(), payload.size()).then([this](){
|
||||
return closeOnComplete ? kj::Promise<void>(kj::READY_NOW) : writeTask();
|
||||
}).attach(kj::mv(payload));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -309,6 +316,12 @@ struct Server::WebsocketConnection : public LaminarClient, public std::streambuf
|
||||
cn->send(payload, websocketpp::frame::opcode::text);
|
||||
}
|
||||
|
||||
void close() override {
|
||||
closeOnComplete = true;
|
||||
outputBuffer.clear();
|
||||
writePaf.fulfiller->fulfill();
|
||||
}
|
||||
|
||||
std::streamsize xsputn(const char* s, std::streamsize sz) override {
|
||||
outputBuffer.append(std::string(s, sz));
|
||||
writePaf.fulfiller->fulfill();
|
||||
@ -320,8 +333,8 @@ struct Server::WebsocketConnection : public LaminarClient, public std::streambuf
|
||||
websocket::connection_ptr cn;
|
||||
std::string outputBuffer;
|
||||
kj::PromiseFulfillerPair<void> writePaf;
|
||||
// TODO: think about this size
|
||||
char ibuf[1024];
|
||||
char ibuf[131072];
|
||||
bool closeOnComplete;
|
||||
};
|
||||
|
||||
Server::Server(LaminarInterface& li, kj::StringPtr rpcBindAddress,
|
||||
@ -331,30 +344,17 @@ Server::Server(LaminarInterface& li, kj::StringPtr rpcBindAddress,
|
||||
ioContext(kj::setupAsyncIo()),
|
||||
tasks(*this)
|
||||
{
|
||||
|
||||
{ // RPC task
|
||||
auto paf = kj::newPromiseAndFulfiller<uint>();
|
||||
// RPC task
|
||||
tasks.add(ioContext.provider->getNetwork().parseAddress(rpcBindAddress, 0)
|
||||
.then(kj::mvCapture(paf.fulfiller,
|
||||
[this](kj::Own<kj::PromiseFulfiller<uint>>&& portFulfiller,
|
||||
kj::Own<kj::NetworkAddress>&& addr) {
|
||||
auto listener = addr->listen();
|
||||
portFulfiller->fulfill(listener->getPort());
|
||||
acceptRpcClient(kj::mv(listener));
|
||||
})));
|
||||
}
|
||||
.then([this](kj::Own<kj::NetworkAddress>&& addr) {
|
||||
acceptRpcClient(addr->listen());
|
||||
}));
|
||||
|
||||
{ // HTTP task
|
||||
auto paf = kj::newPromiseAndFulfiller<uint>();
|
||||
// HTTP task
|
||||
tasks.add(ioContext.provider->getNetwork().parseAddress(httpBindAddress, 0)
|
||||
.then(kj::mvCapture(paf.fulfiller,
|
||||
[this](kj::Own<kj::PromiseFulfiller<uint>>&& portFulfiller,
|
||||
kj::Own<kj::NetworkAddress>&& addr) {
|
||||
auto listener = addr->listen();
|
||||
portFulfiller->fulfill(listener->getPort());
|
||||
acceptHttpClient(kj::mv(listener));
|
||||
})));
|
||||
}
|
||||
.then([this](kj::Own<kj::NetworkAddress>&& addr) {
|
||||
acceptHttpClient(addr->listen());
|
||||
}));
|
||||
}
|
||||
|
||||
Server::~Server() {
|
||||
@ -392,7 +392,10 @@ void Server::acceptHttpClient(kj::Own<kj::ConnectionReceiver>&& listener) {
|
||||
kj::Own<kj::AsyncIoStream>&& connection) {
|
||||
acceptHttpClient(kj::mv(listener));
|
||||
auto conn = kj::heap<WebsocketConnection>(kj::mv(connection), *httpInterface);
|
||||
return conn->pend().exclusiveJoin(conn->writeTask()).attach(std::move(conn));
|
||||
auto promises = kj::heapArrayBuilder<kj::Promise<void>>(2);
|
||||
promises.add(std::move(conn->pend()));
|
||||
promises.add(std::move(conn->writeTask()));
|
||||
return kj::joinPromises(promises.finish()).attach(std::move(conn));
|
||||
}))
|
||||
);
|
||||
}
|
||||
@ -412,9 +415,8 @@ void Server::acceptRpcClient(kj::Own<kj::ConnectionReceiver>&& listener) {
|
||||
// handles stdout/stderr from a child process by sending it to the provided
|
||||
// callback function
|
||||
kj::Promise<void> Server::handleProcessOutput(kj::AsyncInputStream* stream, std::function<void(char*,size_t)> readCb) {
|
||||
// TODO think about this size
|
||||
static char* buffer = new char[1024];
|
||||
return stream->tryRead(buffer, 1, 1024).then([this,stream,readCb](size_t sz) {
|
||||
static char* buffer = new char[131072];
|
||||
return stream->tryRead(buffer, 1, sizeof(buffer)).then([this,stream,readCb](size_t sz) {
|
||||
readCb(buffer, sz);
|
||||
if(sz > 0) {
|
||||
return handleProcessOutput(stream, readCb);
|
||||
|
Loading…
Reference in New Issue
Block a user