diff --git a/src/App.h b/src/App.h index 360fa5fe6..6178ef28f 100644 --- a/src/App.h +++ b/src/App.h @@ -576,6 +576,29 @@ struct TemplatedApp { return std::move(static_cast(*this)); } + BuilderPatternReturnType &&addChildApp(BuilderPatternReturnType *app) { + /* Add this app to httpContextData list over child apps and set onPreOpen */ + httpContext->getSocketContextData()->childApps.push_back((void *) app); + + httpContext->onPreOpen([](struct us_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR fd) -> LIBUS_SOCKET_DESCRIPTOR { + HttpContext *httpContext = (HttpContext *) context; + + int &roundRobin = &httpContext->getSocketContextData()->roundRobin; + BuilderPatternReturnType *receivingApp = (BuilderPatternReturnType *) httpContext->getSocketContextData()->childApps[roundRobin]; + + receivingApp->getLoop()->defer([fd, receivingApp]() { + receivingApp->adoptSocket(fd); + }); + + if (++roundRobin == httpContext->getSocketContextData()->childApps.size()) { + roundRobin = 0; + } + + return fd + 1; + }); + return std::move(static_cast(*this)); + } + /* adopt an externally accepted socket */ BuilderPatternReturnType &&adoptSocket(LIBUS_SOCKET_DESCRIPTOR accepted_fd) { httpContext->adoptAcceptedSocket(accepted_fd); diff --git a/src/HttpContextData.h b/src/HttpContextData.h index 51da48d55..9473660ae 100644 --- a/src/HttpContextData.h +++ b/src/HttpContextData.h @@ -49,6 +49,10 @@ struct alignas(16) HttpContextData { HttpRouter router; void *upgradedWebSocket = nullptr; bool isParsingHttp = false; + + /* If we are main acceptor, distribute to these apps */ + std::vector childApps; + unsigned int roundRobin = 0; }; }