Add blocker to stop; Remove Guard from TaskProcessor; Add stop blocker to Server
This commit is contained in:
parent
6e79e69a2c
commit
9f48938386
3 changed files with 33 additions and 18 deletions
12
include/cserver/components/work_guard.hpp
Normal file
12
include/cserver/components/work_guard.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include <cserver/engine/components.hpp>
|
||||
|
||||
namespace cserver {
|
||||
|
||||
struct StopBlocker {
|
||||
boost::asio::io_service::work work;
|
||||
inline constexpr StopBlocker(auto, auto& context) :
|
||||
work(context.template FindComponent<kBasicTaskProcessorName>().ioContext) {};
|
||||
};
|
||||
|
||||
} // namespace cserver
|
|
@ -122,23 +122,24 @@ struct AsyncConditionVariable {
|
|||
template <utempl::Tuple DependencyGraph, typename T>
|
||||
inline constexpr auto InitComponents(T& ccontext) -> void {
|
||||
static auto& context = ccontext;
|
||||
static auto& ioContext = context.template FindComponent<kBasicTaskProcessorName>().ioContext;
|
||||
static auto& taskProcessor = context.template FindComponent<kBasicTaskProcessorName>();
|
||||
static auto& ioContext = taskProcessor.ioContext;
|
||||
static utempl::Tuple inited = TransformDependencyGraphToInited<AsyncConditionVariable, DependencyGraph>(ioContext);
|
||||
auto work = make_work_guard(ioContext);
|
||||
[]<std::size_t... Is>(std::index_sequence<Is...>){
|
||||
(boost::asio::co_spawn(ioContext, []<auto I>(utempl::Wrapper<I>) -> cserver::Task<> {
|
||||
auto& dependencies = Get<I>(inited);
|
||||
(boost::asio::co_spawn(ioContext, []() -> cserver::Task<> {
|
||||
auto& dependencies = Get<Is>(inited);
|
||||
for(auto* flag : dependencies) {
|
||||
co_await flag->AsyncWait();
|
||||
};
|
||||
Get<I>(context.storage).emplace(utempl::Wrapper<Get<I>(T::kNames)>{}, context);
|
||||
auto& componentInitFlag = GetInitFlagFor<AsyncConditionVariable, I>(ioContext);
|
||||
Get<Is>(context.storage).emplace(utempl::Wrapper<Get<Is>(T::kNames)>{}, context);
|
||||
auto& componentInitFlag = GetInitFlagFor<AsyncConditionVariable, Is>(ioContext);
|
||||
componentInitFlag.NotifyAll();
|
||||
if constexpr(requires{Get<I>(context.storage)->Run();}) {
|
||||
Get<I>(context.storage)->Run();
|
||||
if constexpr(requires{Get<Is>(context.storage)->Run();}) {
|
||||
Get<Is>(context.storage)->Run();
|
||||
};
|
||||
}(utempl::Wrapper<Is>{}), boost::asio::detached), ...);
|
||||
}(), boost::asio::detached), ...);
|
||||
}(std::make_index_sequence<utempl::kTupleSize<decltype(DependencyGraph)>>());
|
||||
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
@ -156,8 +157,8 @@ struct ServiceContext {
|
|||
,storage{} {
|
||||
};
|
||||
inline constexpr auto Run() {
|
||||
this->taskProcessor.Run();
|
||||
impl::InitComponents<DependencyGraph>(*this);
|
||||
this->taskProcessor.Run();
|
||||
};
|
||||
template <utempl::ConstexprString name>
|
||||
inline constexpr auto FindComponent() -> auto& {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <cserver/server/http/http_response.hpp>
|
||||
#include <cserver/engine/coroutine.hpp>
|
||||
#include <cserver/server/http/http_stream.hpp>
|
||||
#include <cserver/components/work_guard.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
|
||||
|
@ -11,7 +12,7 @@ namespace cserver::server::server {
|
|||
|
||||
|
||||
template <utempl::ConstexprString TPName = "basicTaskProcessor", typename TaskProcessor = int, typename... Ts>
|
||||
struct Server {
|
||||
struct Server : StopBlocker {
|
||||
TaskProcessor& taskProcessor;
|
||||
utempl::Tuple<impl::GetTypeFromComponentConfig<Ts>&...> handlers;
|
||||
static constexpr utempl::ConstexprString kName = "server";
|
||||
|
@ -34,13 +35,14 @@ struct Server {
|
|||
});
|
||||
};
|
||||
template <
|
||||
utempl::ConstexprString name,
|
||||
utempl::ConstexprString Name,
|
||||
typename T,
|
||||
std::size_t... Is>
|
||||
inline constexpr Server(std::index_sequence<Is...>, utempl::Wrapper<name>, T& context) :
|
||||
inline constexpr Server(std::index_sequence<Is...>, utempl::Wrapper<Name> name, T& context) :
|
||||
StopBlocker(name, context),
|
||||
taskProcessor(context.template FindComponent<TPName>()),
|
||||
handlers{context.template FindComponent<Get<Is>(kNames)>()...},
|
||||
port(T::kConfig.template Get<name>().template Get<"port">()) {
|
||||
port(T::kConfig.template Get<Name>().template Get<"port">()) {
|
||||
|
||||
};
|
||||
inline constexpr Server(auto name, auto& context) :
|
||||
|
@ -69,11 +71,11 @@ struct Server {
|
|||
http::HTTPRequest request = http::HTTPRequestParser{buffer};
|
||||
bool flag = false;
|
||||
co_await [&]<auto... Is>(std::index_sequence<Is...>) -> cserver::Task<void> {
|
||||
(co_await [&]<auto I>(utempl::Wrapper<I>) -> cserver::Task<void> {
|
||||
if(request.url.path().substr(0, Get<I>(kPaths).size()) == Get<I>(kPaths)) {
|
||||
co_await this->ProcessHandler<I>(std::move(socket), std::move(request));
|
||||
(co_await [&] -> cserver::Task<void> {
|
||||
if(request.url.path().substr(0, Get<Is>(kPaths).size()) == Get<Is>(kPaths)) {
|
||||
co_await this->ProcessHandler<Is>(std::move(socket), std::move(request));
|
||||
};
|
||||
}(utempl::Wrapper<Is>{}), ...);
|
||||
}(), ...);
|
||||
}(std::index_sequence_for<Ts...>());
|
||||
constexpr std::string_view error404 = "HTTP/1.1 404 Not Found\r\n"
|
||||
"Content-Length: 0\r\n"
|
||||
|
|
Loading…
Reference in a new issue