213adee887
Introduce a dedicated streamer-side recording control plane instead of sharing the producer recorder API. - register streamer-owned recorder endpoints as a NATS micro service - add explicit MP4 and MCAP recorder control protobufs and subject helpers - wire recorder lifecycle handling into the pipeline runtime - add MP4 writer and depth-alignment support files used by the new recording flow
94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include "proto/cvmmap_streamer/recorder_control.pb.h"
|
|
|
|
#include <cstdint>
|
|
#include <expected>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <span>
|
|
#include <string>
|
|
|
|
namespace cvmmap_streamer::protocol {
|
|
|
|
enum class RpcErrorCode : std::uint8_t {
|
|
InvalidRequest,
|
|
Unsupported,
|
|
Busy,
|
|
Internal,
|
|
};
|
|
|
|
struct RpcError {
|
|
RpcErrorCode code{RpcErrorCode::Internal};
|
|
std::string message{};
|
|
};
|
|
|
|
struct NatsRequestReplyServerOptions {
|
|
std::string nats_url{};
|
|
std::string instance_name{};
|
|
std::string namespace_name{};
|
|
std::string ipc_prefix{};
|
|
std::string base_name{};
|
|
std::string nats_target_key{};
|
|
std::string backend{"cvmmap-streamer"};
|
|
std::string recording_formats{};
|
|
};
|
|
|
|
class NatsRequestReplyServer {
|
|
public:
|
|
explicit NatsRequestReplyServer(NatsRequestReplyServerOptions options);
|
|
~NatsRequestReplyServer();
|
|
|
|
NatsRequestReplyServer(const NatsRequestReplyServer &) = delete;
|
|
NatsRequestReplyServer &operator=(const NatsRequestReplyServer &) = delete;
|
|
|
|
template <class Request, class Response>
|
|
void register_proto_endpoint(
|
|
std::string endpoint_name,
|
|
std::string subject,
|
|
std::function<std::expected<Response, RpcError>(const Request &)> handler) {
|
|
register_raw_endpoint(
|
|
std::move(endpoint_name),
|
|
std::move(subject),
|
|
[handler = std::move(handler)](std::span<const std::uint8_t> payload) {
|
|
Request request;
|
|
Response response;
|
|
if (!request.ParseFromArray(
|
|
payload.data(),
|
|
static_cast<int>(payload.size()))) {
|
|
response.set_code(cvmmap_streamer::proto::RPC_CODE_INVALID_REQUEST);
|
|
response.set_error_message("failed to parse protobuf request");
|
|
return response.SerializeAsString();
|
|
}
|
|
|
|
auto handled = handler(request);
|
|
if (!handled) {
|
|
response.set_code(to_proto_rpc_code(handled.error().code));
|
|
response.set_error_message(handled.error().message);
|
|
return response.SerializeAsString();
|
|
}
|
|
|
|
return handled->SerializeAsString();
|
|
});
|
|
}
|
|
|
|
[[nodiscard]]
|
|
bool start();
|
|
void stop();
|
|
|
|
private:
|
|
struct Endpoint;
|
|
struct Impl;
|
|
|
|
void register_raw_endpoint(
|
|
std::string endpoint_name,
|
|
std::string subject,
|
|
std::function<std::string(std::span<const std::uint8_t>)> handler);
|
|
|
|
static cvmmap_streamer::proto::RpcCode to_proto_rpc_code(RpcErrorCode code);
|
|
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
|
|
} // namespace cvmmap_streamer::protocol
|