Loading...
Searching...
No Matches
ServeMode.h File Reference
#include "Parameters.h"
#include <cstdint>
#include <string>
#include <vector>

Go to the source code of this file.

Classes

struct  eonc::ServeEndpoint
 Configuration for a single serve endpoint. More...
struct  ServeEndpoint
 Configuration for a single serve endpoint. More...

Namespaces

namespace  eonc
 RAII resource manager for the ARTn C library with global synchronization.

Functions

void eonc::serveMode (const Parameters &params, const std::string &host, uint16_t port)
 Start a single rgpot-compatible Cap'n Proto RPC server.
void eonc::serveMultiple (const std::vector< ServeEndpoint > &endpoints, const Parameters &params)
 Serve multiple potentials concurrently on different ports.
void eonc::serveReplicated (const Parameters &params, const std::string &host, uint16_t base_port, size_t replicas)
 Serve N replicas of the same potential across sequential ports.
void eonc::serveGateway (const Parameters &params, const std::string &host, uint16_t port, size_t pool_size)
 Start a gateway server backed by a pool of potential instances.
void eonc::serveFromConfig (const Parameters &params)
 Start serve mode from config-file parameters.
std::vector< ServeEndpointeonc::parseServeSpec (const std::string &spec)
 Parse a serve configuration string into endpoints.
std::vector< ServeEndpointparseServeSpec (const std::string &spec)
 Parse a serve configuration string into endpoints.
void serveFromConfig (const Parameters &params)
 Start serve mode from config-file parameters.
void serveGateway (const Parameters &params, const std::string &host, uint16_t port, size_t pool_size)
 Start a gateway server backed by a pool of potential instances.
void serveMode (const Parameters &params, const std::string &host, uint16_t port)
 Start a single rgpot-compatible Cap'n Proto RPC server.
void serveMultiple (const std::vector< ServeEndpoint > &endpoints, const Parameters &params)
 Serve multiple potentials concurrently on different ports.
void serveReplicated (const Parameters &params, const std::string &host, uint16_t base_port, size_t replicas)
 Serve N replicas of the same potential across sequential ports.

Function Documentation

◆ parseServeSpec()

std::vector< ServeEndpoint > eonc::parseServeSpec ( const std::string & spec)

Parse a serve configuration string into endpoints.

Accepts comma-separated entries of the form "potential:port" or "potential:host:port". Examples: "lj:12345" "metatomic:12345,lj:12346" "metatomic:0.0.0.0:12345"

Parameters
specThe comma-separated endpoint specification.
Returns
A vector of ServeEndpoint structs.

Definition at line 229 of file ServeMode.cpp.

229 {
230 std::vector<ServeEndpoint> endpoints;
231 std::istringstream stream(spec);
232 std::string token;
233
234 while (std::getline(stream, token, ',')) {
235 // Trim whitespace
236 token.erase(0, token.find_first_not_of(" \t"));
237 token.erase(token.find_last_not_of(" \t") + 1);
238 if (token.empty())
239 continue;
240
241 // Parse "potential:port" or "potential:host:port"
242 size_t first_colon = token.find(':');
243 if (first_colon == std::string::npos) {
244 EONC_LOG_ERROR("Invalid serve spec '{}': expected 'potential:port'",
245 token);
246 continue;
247 }
248
249 std::string pot_str = token.substr(0, first_colon);
250 std::string rest = token.substr(first_colon + 1);
251
252 // Trim parts after colon split
253 pot_str.erase(0, pot_str.find_first_not_of(" \t"));
254 pot_str.erase(pot_str.find_last_not_of(" \t") + 1);
255 rest.erase(0, rest.find_first_not_of(" \t"));
256 rest.erase(rest.find_last_not_of(" \t") + 1);
257
258 // Lowercase the potential name
259 std::transform(pot_str.begin(), pot_str.end(), pot_str.begin(), ::tolower);
260
261 ServeEndpoint ep;
262 ep.potential =
263 magic_enum::enum_cast<PotType>(pot_str, magic_enum::case_insensitive)
264 .value_or(PotType::UNKNOWN);
265
266 if (ep.potential == PotType::UNKNOWN) {
267 EONC_LOG_ERROR("Unknown potential type '{}'", pot_str);
268 continue;
269 }
270
271 size_t second_colon = rest.find(':');
272 if (second_colon != std::string::npos) {
273 // "host:port" format
274 ep.host = rest.substr(0, second_colon);
275 ep.host.erase(0, ep.host.find_first_not_of(" \t"));
276 ep.host.erase(ep.host.find_last_not_of(" \t") + 1);
277 std::string port_str = rest.substr(second_colon + 1);
278 port_str.erase(0, port_str.find_first_not_of(" \t"));
279 port_str.erase(port_str.find_last_not_of(" \t") + 1);
280 ep.port = static_cast<uint16_t>(std::stoi(port_str));
281 } else {
282 // "port" only
283 ep.host = "localhost";
284 ep.port = static_cast<uint16_t>(std::stoi(rest));
285 }
286
287 QUILL_LOG_INFO(eonc::log::get(), "Parsed endpoint: {} on {}:{}",
288 std::string(magic_enum::enum_name(ep.potential)), ep.host,
289 ep.port);
290 endpoints.push_back(ep);
291 }
292
293 return endpoints;
294}
#define EONC_LOG_ERROR(...)
Definition EonLogger.h:262
quill::Logger * get() noexcept
Get or create the default "combi" logger.
Definition EonLogger.h:44
Configuration for a single serve endpoint.
Definition ServeMode.h:27
std::string host
Definition ServeMode.h:29

◆ serveFromConfig()

void eonc::serveFromConfig ( const Parameters & params)

Start serve mode from config-file parameters.

Reads serve_options from params and dispatches to the appropriate mode:

  • If endpoints is set, uses multi-model serve (serveMultiple).
  • If gateway_port > 0, uses gateway mode (serveGateway).
  • Otherwise, uses replicated mode (serveReplicated).
Parameters
paramsThe eOn parameters with serve_options populated.

Definition at line 200 of file ServeMode.cpp.

200 {
201 const auto &opts = params.serve_options;
202
203 // Multi-model endpoints take priority
204 if (!opts.endpoints.empty()) {
205 auto endpoints = parseServeSpec(opts.endpoints);
206 if (endpoints.empty()) {
207 EONC_LOG_ERROR("No valid endpoints in spec: {}", opts.endpoints);
208 return;
209 }
210 serveMultiple(endpoints, params);
211 return;
212 }
213
214 // Gateway mode
215 if (opts.gateway_port > 0) {
216 size_t pool = (opts.replicas > 0) ? opts.replicas : 1;
217 serveGateway(params, opts.host, opts.gateway_port, pool);
218 return;
219 }
220
221 // Replicated mode (default)
222 serveReplicated(params, opts.host, opts.port, opts.replicas);
223}
std::vector< ServeEndpoint > parseServeSpec(const std::string &spec)
Parse a serve configuration string into endpoints.
void serveGateway(const Parameters &params, const std::string &host, uint16_t port, size_t pool_size)
Start a gateway server backed by a pool of potential instances.
void serveMultiple(const std::vector< ServeEndpoint > &endpoints, const Parameters &params)
Serve multiple potentials concurrently on different ports.
Definition ServeMode.cpp:79
void serveReplicated(const Parameters &params, const std::string &host, uint16_t base_port, size_t replicas)
Serve N replicas of the same potential across sequential ports.
struct eonc::Parameters::serve_options_t serve_options

◆ serveGateway()

void eonc::serveGateway ( const Parameters & params,
const std::string & host,
uint16_t port,
size_t pool_size )

Start a gateway server backed by a pool of potential instances.

Creates pool_size instances of the configured potential and serves them behind a single gateway port. Incoming requests are dispatched round-robin across the pool. This gives clients a single endpoint while spreading load.

Parameters
paramsThe eOn parameters (potential_options.potential must be set).
hostThe hostname to listen on.
portThe gateway port.
pool_sizeNumber of potential instances in the pool.

Definition at line 167 of file ServeMode.cpp.

168 {
169 if (pool_size == 0) {
170 EONC_LOG_ERROR("Pool size must be >= 1");
171 return;
172 }
173
174 auto pot_type = params.potential_options.potential;
175 EONC_LOG_INFO("Creating pool of {} {} instances for gateway on {}:{}",
176 pool_size, std::string(magic_enum::enum_name(pot_type)), host,
177 port);
178
179 std::vector<ForceCallback> pool;
180 pool.reserve(pool_size);
181
182 for (size_t i = 0; i < pool_size; ++i) {
183 auto eon_pot = eonc::helpers::makePotential(params);
184 if (!eon_pot) {
185 EONC_LOG_ERROR("Failed to create potential instance {}/{}", i + 1,
186 pool_size);
187 return;
188 }
189 pool.push_back(makeForceCallback(std::move(eon_pot)));
190 }
191
192 EONC_LOG_INFO("Pool ready, starting gateway server");
193 startPooledRpcServer(std::move(pool), host, port);
194}
#define EONC_LOG_INFO(...)
Definition EonLogger.h:250
void startPooledRpcServer(std::vector< ForceCallback > pool, const std::string &host, uint16_t port)
Start a blocking Cap'n Proto RPC server backed by a pool of force callbacks dispatched round-robin.
struct eonc::Parameters::potential_options_t potential_options
std::shared_ptr< Potential > makePotential(const Parameters &params)

◆ serveMode()

void eonc::serveMode ( const Parameters & params,
const std::string & host,
uint16_t port )

Start a single rgpot-compatible Cap'n Proto RPC server.

Wraps eOn's Potential::force() as an rgpot PotentialBase and serves it over Cap'n Proto RPC. Blocks until the server is killed.

Parameters
paramsThe eOn parameters (potential_options.potential must be set).
hostThe hostname to listen on (e.g., "localhost" or "*").
portThe TCP port to listen on.

Definition at line 56 of file ServeMode.cpp.

57 {
58 auto pot_type = params.potential_options.potential;
59 EONC_LOG_INFO("Creating potential: {}",
60 std::string(magic_enum::enum_name(pot_type)));
61
62 auto eon_pot = eonc::helpers::makePotential(params);
63 if (!eon_pot) {
64 EONC_LOG_ERROR("Failed to create potential of type {}",
65 std::string(magic_enum::enum_name(pot_type)));
66 return;
67 }
68
69 auto callback = makeForceCallback(std::move(eon_pot));
70
71 // Blocks until killed (runs Cap'n Proto event loop)
72 startRpcServer(std::move(callback), host, port);
73}
void startRpcServer(ForceCallback callback, const std::string &host, uint16_t port)
Start a blocking Cap'n Proto RPC server using a force callback.

◆ serveMultiple()

void eonc::serveMultiple ( const std::vector< ServeEndpoint > & endpoints,
const Parameters & params )

Serve multiple potentials concurrently on different ports.

Each endpoint gets its own thread, its own potential instance, and its own Cap'n Proto event loop. All threads block until SIGINT/SIGTERM.

Parameters
endpointsList of {potential, host, port} configurations.
paramsBase eOn parameters (potential type is overridden per endpoint).

Definition at line 79 of file ServeMode.cpp.

80 {
81 if (endpoints.empty()) {
82 EONC_LOG_ERROR("No serve endpoints specified");
83 return;
84 }
85
86 // Single endpoint: run in the main thread (no extra overhead)
87 if (endpoints.size() == 1) {
88 auto params = base_params;
89 params.potential_options.potential = endpoints[0].potential;
90 serveMode(params, endpoints[0].host, endpoints[0].port);
91 return;
92 }
93
94 // Multiple endpoints: one thread per server
95 EONC_LOG_INFO("Starting {} concurrent RPC servers", endpoints.size());
96
97 std::vector<std::thread> threads;
98 threads.reserve(endpoints.size());
99
100 for (const auto &ep : endpoints) {
101 threads.emplace_back([&base_params, ep]() {
102 auto params = base_params;
103 params.potential_options.potential = ep.potential;
104 auto pot_name = std::string(magic_enum::enum_name(ep.potential));
105
106 EONC_LOG_INFO("[{}:{}] Creating potential: {}", ep.host, ep.port,
107 pot_name);
108
109 auto eon_pot = eonc::helpers::makePotential(params);
110 if (!eon_pot) {
111 EONC_LOG_ERROR("[{}:{}] Failed to create potential {}", ep.host,
112 ep.port, pot_name);
113 return;
114 }
115
116 auto callback = makeForceCallback(std::move(eon_pot));
117 startRpcServer(std::move(callback), ep.host, ep.port);
118 });
119 }
120
121 // Wait for all threads (they block until killed)
122 for (auto &t : threads) {
123 if (t.joinable()) {
124 t.join();
125 }
126 }
127}
void serveMode(const Parameters &params, const std::string &host, uint16_t port)
Start a single rgpot-compatible Cap'n Proto RPC server.
Definition ServeMode.cpp:56

◆ serveReplicated()

void eonc::serveReplicated ( const Parameters & params,
const std::string & host,
uint16_t base_port,
size_t replicas )

Serve N replicas of the same potential across sequential ports.

Starts replicas threads, each serving the same potential type on ports base_port, base_port+1, ..., base_port+replicas-1.

Parameters
paramsThe eOn parameters (potential_options.potential must be set).
hostThe hostname to listen on.
base_portThe first port; replicas use base_port+0 .. base_port+N-1.
replicasNumber of concurrent server instances.

Definition at line 133 of file ServeMode.cpp.

134 {
135 if (replicas == 0) {
136 EONC_LOG_ERROR("Replicas must be >= 1");
137 return;
138 }
139 if (replicas == 1) {
140 serveMode(params, host, base_port);
141 return;
142 }
143
144 EONC_LOG_INFO("Starting {} replicated servers on ports {}-{}", replicas,
145 base_port, base_port + replicas - 1);
146
147 std::vector<std::thread> threads;
148 threads.reserve(replicas);
149
150 for (size_t i = 0; i < replicas; ++i) {
151 uint16_t port = static_cast<uint16_t>(base_port + i);
152 threads.emplace_back(
153 [&params, &host, port]() { serveMode(params, host, port); });
154 }
155
156 for (auto &t : threads) {
157 if (t.joinable()) {
158 t.join();
159 }
160 }
161}