Skip to content

Commit d8c826a

Browse files
committed
engine: Refactor server into interface and implementation
1 parent 68ec539 commit d8c826a

File tree

5 files changed

+251
-120
lines changed

5 files changed

+251
-120
lines changed

engine/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ add_executable(${target}
6969
src/coordinator.cpp
7070
src/plugins/nop_controller.cpp
7171
src/plugins/nop_simulator.cpp
72+
src/server.cpp
7273
src/simulation.cpp
7374
src/simulation_context.cpp
7475
src/utility/command.cpp

engine/src/server.cpp

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright 2022 Robert Bosch GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
/**
19+
* \file server.cpp
20+
* \see server.hpp
21+
*/
22+
23+
#include "server.hpp"
24+
25+
#include <memory> // for unique_ptr<>
26+
#include <utility> // for make_pair
27+
28+
#include <cloe/registrar.hpp> // for HandlerType
29+
#include <cloe/utility/output_serializer_json.hpp> // for JsonFileSerializer
30+
31+
#include <oak/server.hpp> // for Server, StaticRegistrar, ...
32+
33+
namespace engine {
34+
35+
class ServerImpl : public Server {
36+
public:
37+
ServerImpl(const cloe::ServerConf& config) : Server(config) {
38+
auto rl = logger();
39+
40+
// clang-format off
41+
static_registrar_.set_prefix(config.static_prefix);
42+
static_registrar_.set_logger([rl] (auto endpoint) {
43+
rl->debug("Register static endpoint: {}", endpoint);
44+
});
45+
46+
static_api_registrar_.set_prefix(config.api_prefix);
47+
static_api_registrar_.set_logger([rl] (auto endpoint) {
48+
rl->debug("Register static endpoint: {}", endpoint);
49+
});
50+
51+
locked_api_registrar_.set_prefix(config.api_prefix);
52+
locked_api_registrar_.set_logger([rl] (auto endpoint) {
53+
rl->debug("Register dynamic endpoint: {}", endpoint);
54+
});
55+
56+
buffer_api_registrar_.set_prefix(config.api_prefix);
57+
buffer_api_registrar_.set_logger([rl] (auto endpoint) {
58+
rl->debug("Register buffered endpoint: {}", endpoint);
59+
});
60+
// clang-format on
61+
}
62+
63+
~ServerImpl() { stop(); }
64+
65+
public:
66+
bool is_listening() const override { return server_.is_listening(); }
67+
68+
bool is_streaming() const override { return is_streaming_; }
69+
70+
void start() override {
71+
assert(!is_listening());
72+
73+
logger()->info("Listening at: http://{}:{}", config_.listen_address, config_.listen_port);
74+
server_.set_address(config_.listen_address);
75+
server_.set_port(config_.listen_port);
76+
server_.set_threads(config_.listen_threads);
77+
server_.listen();
78+
}
79+
80+
void init_stream(const std::string& filename) override {
81+
serializer_ = make_json_file_serializer(cloe::utility::JsonFileType::JSON_GZIP, logger());
82+
serializer_->open_file(filename);
83+
}
84+
85+
void stop() override {
86+
if (is_listening()) {
87+
logger()->info("Stopping server...");
88+
server_.stop();
89+
}
90+
if (serializer_ != nullptr) {
91+
serializer_->close_file();
92+
}
93+
}
94+
95+
void enroll(cloe::Registrar& r) override {
96+
r.register_api_handler(
97+
"/endpoints", cloe::HandlerType::STATIC,
98+
[this](const cloe::Request&, cloe::Response& r) { r.write(this->server_.endpoints()); });
99+
}
100+
101+
oak::Registrar static_registrar() override { return static_registrar_.with("", nullptr); }
102+
103+
oak::ProxyRegistrar<cloe::HandlerType> api_registrar() override {
104+
return oak::ProxyRegistrar<cloe::HandlerType>({
105+
std::make_pair(cloe::HandlerType::STATIC, &static_api_registrar_),
106+
std::make_pair(cloe::HandlerType::DYNAMIC, &locked_api_registrar_),
107+
std::make_pair(cloe::HandlerType::BUFFERED, &buffer_api_registrar_),
108+
});
109+
}
110+
111+
void refresh_buffer_start_stream() override {
112+
is_streaming_ = serializer_ != nullptr;
113+
if (is_listening() || is_streaming()) {
114+
buffer_api_registrar_.refresh_buffer();
115+
}
116+
if (is_streaming()) {
117+
// Write static endpoints at the beginning of the file.
118+
write_data_stream(static_api_registrar_.endpoints());
119+
write_data_stream(locked_api_registrar_.endpoints());
120+
write_data_stream(buffer_api_registrar_.endpoints());
121+
}
122+
}
123+
124+
void refresh_buffer() override {
125+
if (is_listening() || is_streaming()) {
126+
buffer_api_registrar_.refresh_buffer();
127+
}
128+
if (is_streaming()) {
129+
write_data_stream(locked_api_registrar_.endpoints());
130+
write_data_stream(buffer_api_registrar_.endpoints());
131+
}
132+
}
133+
134+
Defer lock() override {
135+
auto lock = locked_api_registrar_.lock();
136+
return Defer([&]() { lock.release(); });
137+
}
138+
139+
private:
140+
void write_data_stream(const std::vector<std::string>& endpoints) const {
141+
auto j = server_.endpoints_to_json(endpoints);
142+
if (!j.empty()) {
143+
serializer_->serialize(j);
144+
}
145+
}
146+
147+
private:
148+
oak::Server server_;
149+
oak::StaticRegistrar static_registrar_{&server_, config_.static_prefix, nullptr};
150+
oak::StaticRegistrar static_api_registrar_{&server_, config_.api_prefix, nullptr};
151+
oak::LockedRegistrar locked_api_registrar_{&server_, config_.api_prefix, nullptr};
152+
oak::BufferRegistrar buffer_api_registrar_{&server_, config_.api_prefix, nullptr};
153+
bool is_streaming_{false};
154+
std::unique_ptr<cloe::utility::JsonFileSerializer> serializer_;
155+
};
156+
157+
std::unique_ptr<Server> make_server(const cloe::ServerConf& c) {
158+
return std::make_unique<ServerImpl>(c);
159+
}
160+
161+
} // namespace engine

0 commit comments

Comments
 (0)