update doxygen comments for concurrent logger

This commit is contained in:
Aaron Po
2026-05-14 21:21:28 -04:00
parent 74f11b57e2
commit a4968eb043
6 changed files with 161 additions and 88 deletions

View File

@@ -2,8 +2,11 @@
#define BIERGARTEN_PIPELINE_INCLUDES_BIERGARTEN_DATA_GENERATOR_H_ #define BIERGARTEN_PIPELINE_INCLUDES_BIERGARTEN_DATA_GENERATOR_H_
/** /**
* @file biergarten_pipeline_orchestrator.h * @file biergarten_data_generator.h
* @brief Core orchestration class for pipeline data generation. * @brief Orchestration for end-to-end brewery data generation pipeline.
*
* Intent: Coordinates location loading, enrichment, and generation phases
* to produce a complete dataset. Coordinates dependencies via composition root.
*/ */
#include <memory> #include <memory>
@@ -23,13 +26,14 @@
*/ */
class BiergartenPipelineOrchestrator { class BiergartenPipelineOrchestrator {
public: public:
/** /**
* @brief Construct a BiergartenDataGenerator with injected dependencies. * @brief Constructs the orchestrator with injected pipeline dependencies.
* *
* @param context_service Context provider for sampled locations. * @param context_service Provides regional context for locations.
* @param generator Brewery and user data generator. * @param generator Implementation (Llama or Mock) for brewery/user generation.
* @param exporter Storage backend for generated brewery data. * @param exporter Database backend for persisting generated records.
*/ * @param application_options CLI configuration and paths.
*/
BiergartenPipelineOrchestrator( BiergartenPipelineOrchestrator(
std::unique_ptr<IEnrichmentService> context_service, std::unique_ptr<IEnrichmentService> context_service,
std::unique_ptr<DataGenerator> generator, std::unique_ptr<DataGenerator> generator,
@@ -55,10 +59,11 @@ class BiergartenPipelineOrchestrator {
/// @brief Generator dependency selected in the composition root. /// @brief Generator dependency selected in the composition root.
std::unique_ptr<DataGenerator> generator_; std::unique_ptr<DataGenerator> generator_;
/// @brief Storage backend for generated brewery records. /// @brief Storage backend for generated brewery records.
std::unique_ptr<IExportService> exporter_; std::unique_ptr<IExportService> exporter_;
ApplicationOptions application_options_; /// @brief CLI configuration: paths, model settings, generation parameters.
ApplicationOptions application_options_;
/** /**
* @brief Load locations from JSON and sample cities. * @brief Load locations from JSON and sample cities.

View File

@@ -1,7 +1,3 @@
//
// Created by aaronpo on 29/04/2026.
//
#ifndef BIERGARTEN_PIPELINE_INCLUDES_CONCURRENCY_BOUNDED_CHANNEL_H_ #ifndef BIERGARTEN_PIPELINE_INCLUDES_CONCURRENCY_BOUNDED_CHANNEL_H_
#define BIERGARTEN_PIPELINE_INCLUDES_CONCURRENCY_BOUNDED_CHANNEL_H_ #define BIERGARTEN_PIPELINE_INCLUDES_CONCURRENCY_BOUNDED_CHANNEL_H_
@@ -13,17 +9,19 @@
/** /**
* @file bounded_channel.h * @file bounded_channel.h
* @brief A thread-safe, bounded multi-producer/multi-consumer channel. * @brief Thread-safe, bounded multi-producer/multi-consumer synchronous channel.
*
* Intent: Enables asynchronous inter-thread communication with backpressure.
* Models a synchronous channel where producers/consumers block on capacity limits.
*/ */
// --------------------------------------------------------------------------- /**
// BoundedChannel<T> * @class BoundedChannel
// * @brief MPMC channel with fixed capacity and blocking semantics.
// Models a synchronous channel with a fixed-capacity internal buffer. *
// Producers block when the buffer is full (backpressure). * Producers block when buffer is full; consumers block when empty.
// Consumers block when the buffer be empty. * Close() unblocks all waiters and signals channel exhaustion.
// Calling close() unblocks all waiting threads and signals exhaustion. */
// ---------------------------------------------------------------------------
template <typename T> template <typename T>
class BoundedChannel { class BoundedChannel {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------

View File

@@ -1,10 +1,9 @@
/** /**
* @file services/logging/channel_logger.h * @file services/logging/channel_logger.h
* @brief Channel-backed implementation of the Logger interface. * @brief Channel-backed producer for asynchronous pipeline logging.
* *
* ChannelLogger constructs LogEntry values and forwards them to a * Intent: Decouple logging from synchronous I/O by forwarding entries to a
* BoundedChannel<LogEntry> for asynchronous consumption by LogConsumer. * bounded channel. LogConsumer drains the channel on a dedicated thread.
* The channel is injected by reference; ChannelLogger does not own it.
*/ */
#ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_CHANNEL_LOGGER_H_ #ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_CHANNEL_LOGGER_H_
@@ -16,22 +15,40 @@
#include "services/logging/log_entry.h" #include "services/logging/log_entry.h"
#include "services/logging/logger.h" #include "services/logging/logger.h"
/**
* @class ChannelLogger
* @brief ILogger implementation that sends entries to a BoundedChannel.
*
* Non-copyable, non-movable. Holds a non-owning reference to the channel.
*/
class ChannelLogger final : public ILogger { class ChannelLogger final : public ILogger {
public: public:
explicit ChannelLogger(BoundedChannel<LogEntry>& channel); /**
* @brief Construct a channel-backed logger.
*
* @param channel Reference to bounded channel for log entry transfer.
* Channel must outlive this logger instance.
*/
explicit ChannelLogger(BoundedChannel<LogEntry>& channel);
ChannelLogger(const ChannelLogger&) = delete; ChannelLogger(const ChannelLogger&) = delete;
ChannelLogger& operator=(const ChannelLogger&) = delete; ChannelLogger& operator=(const ChannelLogger&) = delete;
ChannelLogger(ChannelLogger&&) = delete; ChannelLogger(ChannelLogger&&) = delete;
ChannelLogger& operator=(ChannelLogger&&) = delete; ChannelLogger& operator=(ChannelLogger&&) = delete;
~ChannelLogger() override = default; ~ChannelLogger() override = default;
void Log(LogLevel level, PipelinePhase phase, /**
std::string_view message) override; * @brief Queue a log entry for asynchronous processing.
*
* Blocks if the channel is full (backpressure). Returns immediately
* if the channel is closed.
*/
void Log(LogLevel level, PipelinePhase phase,
std::string_view message) override;
private: private:
BoundedChannel<LogEntry>& channel_; BoundedChannel<LogEntry>& channel_;
}; };
#endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_CHANNEL_LOGGER_H_ #endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_CHANNEL_LOGGER_H_

View File

@@ -1,10 +1,10 @@
/** /**
* @file services/logging/log_consumer.h * @file services/logging/log_consumer.h
* @brief Dedicated log drain worker for the pipeline logging channel. * @brief Dedicated log consumer/drain for asynchronous pipeline logging.
* *
* LogConsumer runs on its own thread, draining LogEntry items from a * Intent: Dequeue LogEntry values from a BoundedChannel on a dedicated thread
* BoundedChannel<LogEntry> and forwarding them to spdlog. Exits cleanly * and forward them to spdlog for I/O and formatting. Decouples application
* when the channel is closed. * logic from logging latency.
*/ */
#ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_CONSUMER_H_ #ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_CONSUMER_H_
@@ -17,28 +17,43 @@
#include "concurrency/bounded_channel.h" #include "concurrency/bounded_channel.h"
#include "services/logging/log_entry.h" #include "services/logging/log_entry.h"
/**
* @class LogConsumer
* @brief Consumes log entries from channel and forwards to spdlog.
*
* Non-copyable, non-movable. Designed to run on its own dedicated std::thread.
* Drains the channel until closure, then exits cleanly.
*/
class LogConsumer { class LogConsumer {
public: public:
explicit LogConsumer(BoundedChannel<LogEntry>& channel); /**
* @brief Construct a log consumer.
*
* @param channel Reference to bounded channel for log entry retrieval.
* Channel must outlive this consumer instance.
*/
explicit LogConsumer(BoundedChannel<LogEntry>& channel);
LogConsumer(const LogConsumer&) = delete; LogConsumer(const LogConsumer&) = delete;
LogConsumer& operator=(const LogConsumer&) = delete; LogConsumer& operator=(const LogConsumer&) = delete;
LogConsumer(LogConsumer&&) = delete; LogConsumer(LogConsumer&&) = delete;
LogConsumer& operator=(LogConsumer&&) = delete; LogConsumer& operator=(LogConsumer&&) = delete;
/** /**
* @brief Drains the channel until it is closed. * @brief Main loop: drain channel and forward entries to spdlog.
* *
* Intended to be run on a dedicated std::thread. Exits when: * Intended to be called once on a dedicated thread. Returns when:
* - The channel is closed and the queue is fully drained. * - Channel is closed AND all queued entries are drained.
*/ *
void Run(); * Thread-safe for use from multiple ChannelLogger instances on other threads.
*/
void Run();
private: private:
BoundedChannel<LogEntry>& channel_; BoundedChannel<LogEntry>& channel_;
static spdlog::level::level_enum ToSpdlogLevel(LogLevel level); static spdlog::level::level_enum ToSpdlogLevel(LogLevel level);
static std::string ToString(PipelinePhase phase); static std::string ToString(PipelinePhase phase);
}; };
#endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_CONSUMER_H_ #endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_CONSUMER_H_

View File

@@ -1,10 +1,9 @@
/** /**
* @file services/logging/log_entry.h * @file services/logging/log_entry.h
* @brief POD struct representing a single log event in the pipeline. * @brief POD log entry structure for asynchronous pipeline logging.
* *
* LogEntry is produced by PipelineLogger and consumed by LogWorker via * Intent: Lightweight, move-safe data transfer between logging producer
* BoundedChannel<LogEntry>. All fields are value types so entries are * (ChannelLogger) and consumer (LogConsumer) via BoundedChannel<LogEntry>.
* safely movable across the channel without shared ownership.
*/ */
#ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_ENTRY_H_ #ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_ENTRY_H_
@@ -13,29 +12,54 @@
#include <chrono> #include <chrono>
#include <string> #include <string>
/**
* @enum LogLevel
* @brief Severity levels for log entries.
*/
enum class LogLevel { enum class LogLevel {
Debug, Debug, ///< Development/debugging information.
Info, Info, ///< General informational messages.
Warn, Warn, ///< Warning conditions.
Error, Error, ///< Error conditions.
}; };
/**
* @enum PipelinePhase
* @brief Execution phases for contextual logging.
*
* Used to tag log entries by their processing stage, enabling phase-specific
* analysis and filtering of the execution timeline.
*/
enum class PipelinePhase { enum class PipelinePhase {
Startup, Startup, ///< Initialization and validation.
UserGeneration, UserGeneration, ///< User profile generation.
BreweryAndBeerGeneration, BreweryAndBeerGeneration, ///< Brewery and beer data generation.
CheckinGeneration, CheckinGeneration, ///< Checkin (visit) record generation.
RatingGeneration, RatingGeneration, ///< Rating and review generation.
FollowGeneration, FollowGeneration, ///< Follow relationship generation.
Teardown, Teardown, ///< Finalization and cleanup.
}; };
/**
* @struct LogEntry
* @brief Single log event for asynchronous processing.
*
* All fields are value types, allowing safe move semantics across
* BoundedChannel without shared ownership or synchronization overhead.
*/
struct LogEntry { struct LogEntry {
std::chrono::system_clock::time_point timestamp = /// @brief Timestamp when entry was created.
std::chrono::system_clock::now(); std::chrono::system_clock::time_point timestamp =
LogLevel level; std::chrono::system_clock::now();
PipelinePhase phase;
std::string message; /// @brief Severity level of this entry.
LogLevel level;
/// @brief Pipeline phase when entry was logged.
PipelinePhase phase;
/// @brief Log message text.
std::string message;
}; };
#endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_ENTRY_H_ #endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOG_ENTRY_H_

View File

@@ -1,9 +1,9 @@
/** /**
* @file services/logging/logger.h * @file services/logging/logger.h
* @brief Abstract interface for pipeline logging. * @brief Abstract logging interface for pipeline components.
* *
* Kept intentionally narrow. Components that need to log depend on Logger, * Intent: Decouple logging from channel/worker implementation details.
* not on PipelineLogger or any channel type. * All pipeline components depend on ILogger, enabling swappable backends.
*/ */
#ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOGGER_H_ #ifndef BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOGGER_H_
@@ -15,17 +15,31 @@
#include "services/logging/log_entry.h" #include "services/logging/log_entry.h"
/**
* @class ILogger
* @brief Minimal interface for submitting log entries.
*
* Non-copyable and non-movable. Implementations are typically short-lived,
* created and owned by the composition root.
*/
class ILogger { class ILogger {
public: public:
ILogger() = default; ILogger() = default;
ILogger(const ILogger&) = delete; ILogger(const ILogger&) = delete;
ILogger& operator=(const ILogger&) = delete; ILogger& operator=(const ILogger&) = delete;
ILogger(ILogger&&) = delete; ILogger(ILogger&&) = delete;
ILogger& operator=(ILogger&&) = delete; ILogger& operator=(ILogger&&) = delete;
virtual ~ILogger() = default; virtual ~ILogger() = default;
virtual void Log(LogLevel level, PipelinePhase phase, /**
std::string_view message) = 0; * @brief Submit a log entry to the logging subsystem.
*
* @param level Log level (Debug, Info, Warn, Error).
* @param phase Pipeline execution phase (Startup, Generation, Teardown, etc.).
* @param message Log message text.
*/
virtual void Log(LogLevel level, PipelinePhase phase,
std::string_view message) = 0;
}; };
#endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOGGER_H_ #endif // BIERGARTEN_PIPELINE_INCLUDES_SERVICES_LOGGING_LOGGER_H_