ores.storage.service

Table of Contents

1. Summary

ores.storage.service is the process that lets a component reach storage over the bus. It binds the operation set's subjects, authenticates the caller and checks the operation's permission code before it acts, and calls ores.storage.core to move the bytes.

2. Inputs

  • The bus endpoint and the service's own configuration.
  • An authenticated request on one of the operation set's subjects.

3. Outputs

  • One reply per request, carrying the protocol's result and, where the operation returns data, the object's metadata or page.

4. Entry points

  • src/main.cpp — the process entry point.
  • include/ores.storage.service/messaging/registrar.hpp — the handler registration.

5. Dependencies

  • ores.storage.core — the implementation it serves.
  • ores.service — the domain service runner every service shares.
  • ores.nats — the transport.

6. Implementation

ores.storage/service is the first service past the ores.cpp.service-app stub, so its implementation lives in its own model rather than in the generated src/app/application.cpp. Each block below fills one paste point of ores.cpp.service-app.application_impl; the run body suppresses the stub.

6.1. Extra includes

#include "ores.nats/service/client.hpp"
#include "ores.service/service/domain_service_runner.hpp"
#include "ores.service/service/heartbeat_publisher.hpp"
#include "ores.storage.core/filesystem/local_store.hpp"
#include "ores.storage.service/messaging/registrar.hpp"
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <memory>
#include <utility>

6.2. Namespace preamble

namespace {
constexpr std::string_view service_name = "ores.storage.service";
constexpr std::string_view service_version = ORES_VERSION;
}

6.3. Run body

The store is the one the HTTP routes are given: two front doors onto the same tree, which is what makes a put over the bus and a put over HTTP leave the same object.

BOOST_LOG_SEV(lg(), info) << ores::utility::version::format_startup_message(
    "ores.storage.service", 0, 1);

ores::nats::service::client nats(cfg.nats);
nats.connect();

// The store is the one the HTTP routes are given: two front doors onto the
// same tree, which is what makes a put over the bus and a put over HTTP
// leave the same object.
ores::storage::filesystem::local_store store(cfg.storage_dir);

// Bound before the await, so no lambda of the call lives in this frame; see run().
auto service_run = ores::service::service::run(
    io_ctx,
    nats,
    make_context(cfg.database),
    "ores.storage.service",
    [store](auto& n, auto c, auto v) {
        return ores::storage::service::messaging::registrar::register_handlers(
            n, std::move(c), std::move(v), store);
    },
    [&nats](boost::asio::io_context& ioc) {
        auto hb = std::make_shared<ores::service::service::heartbeat_publisher>(
            std::string(service_name), std::string(service_version), nats);
        boost::asio::co_spawn(ioc, [hb]() { return hb->run(); }, boost::asio::detached);
    });
co_await std::move(service_run);
co_return;

7. Options

The options this service takes beyond logging, NATS and the database. Codegen writes the member, its wire field, its command-line declaration and its assignment from each entry.

7.1. storage_dir

Root directory the buckets live under.

It must be the same directory the HTTP storage routes are given, because the two interfaces serve the same objects through the same store.

8. See also

The service instantiates the wire codecs its handlers carry, and ores.utility only exposes them: it instantiates none of the templates itself, so --as-needed drops msgpack-c from the utility's DT_NEEDED and the service fails at load with an undefined msgpack-c symbol. The carrier is linked where it is used.

find_package(msgpack-c CONFIG REQUIRED)

target_link_libraries(${lib_target_name}
    PUBLIC
        msgpack-c)
target_link_libraries(${tests_target_name}
    PRIVATE
        ${lib_target_name}
        ores.testing.lib
        ores.logging.lib
        Catch2::Catch2
        faker-cxx::faker-cxx
        ores.openssl_cleanup
        Threads::Threads)

Emacs 29.3 (Org mode 9.6.15)