Skip to content

deps: Resolve bidirectional thread_system dependency risk #252

Description

@kcenon

Summary

Resolve the bidirectional dependency risk between logger_system and thread_system by enforcing a single direction of integration and documenting safe usage patterns.

5W1H Specification

  • Who: logger_system maintainers
  • What: Clarify and enforce unidirectional dependency with thread_system
  • Where: integration/thread_system_integration.h, core/thread_integration_detector.h
  • When: v0.4.0.0 release cycle
  • Why:
    • logger_system can optionally use thread_system for async file I/O (LOGGER_HAS_THREAD_SYSTEM)
    • thread_system can optionally use logger_system for logging (BUILD_WITH_LOGGER_SYSTEM)
    • Both directions enabled simultaneously creates circular dependency risk
  • How:
    1. Enforce that only ONE direction should be enabled in production
    2. Add CMake conflict detection
    3. Use common_system IExecutor as neutral dependency

Priority

HIGH - Risk level: MODERATE per CROSS_MODULE_INTEGRATION.md

Current Dependency State

           ┌──────────────────────┐
           │    thread_system     │
           │                      │
           │  logger_system_      │◄──── Uses for logging output
           │  adapter.h           │
           └──────────┬───────────┘
                      │
    BUILD_WITH_       │  LOGGER_HAS_
    LOGGER_SYSTEM     │  THREAD_SYSTEM
                      │
           ┌──────────▼───────────┐
           │    logger_system     │
           │                      │
           │  thread_system_      │◄──── Uses for async file I/O
           │  integration.h       │
           └──────────────────────┘

Current Integration Files

File Guard Purpose
integration/thread_system_integration.h #ifdef LOGGER_HAS_THREAD_SYSTEM Use thread_pool for async writes
core/thread_integration_detector.h __has_include() Auto-detect thread_system availability
backends/monitoring_backend.h USE_MONITORING_SYSTEM Log metrics to monitoring

Proposed Resolution

Option A: logger_system uses thread_system only (Recommended)

# logger_system/CMakeLists.txt
option(LOGGER_USE_THREAD_SYSTEM "Use thread_system for async I/O" ON)

if(LOGGER_USE_THREAD_SYSTEM)
    find_package(thread_system QUIET)
    if(thread_system_FOUND)
        target_compile_definitions(${PROJECT_NAME} PUBLIC LOGGER_HAS_THREAD_SYSTEM)
        target_link_libraries(${PROJECT_NAME} PUBLIC thread_system::thread_system)
    endif()
endif()

# CONFLICT DETECTION: warn if reverse dependency is detected
if(DEFINED BUILD_WITH_LOGGER_SYSTEM AND BUILD_WITH_LOGGER_SYSTEM)
    message(WARNING 
        "Bidirectional dependency detected: thread_system → logger_system AND "
        "logger_system → thread_system. This may cause build order issues. "
        "Consider using only one direction.")
endif()

Option B: Use common_system IExecutor (Neutral Dependency)

// logger_system uses IExecutor interface, not thread_system directly
class async_logger {
public:
    explicit async_logger(std::shared_ptr<common::interfaces::IExecutor> executor)
        : executor_(std::move(executor)) {}

    auto log(const log_entry& entry) -> void {
        executor_->execute([this, entry] {
            write_to_backend(entry);
        });
    }

private:
    std::shared_ptr<common::interfaces::IExecutor> executor_;
};

// thread_system provides IExecutor implementation
// No compile-time dependency between logger and thread

Tasks

  • Add CMake conflict detection for bidirectional dependency
  • Document recommended configuration (logger → thread, not reverse)
  • Migrate from direct thread_system dependency to IExecutor interface
  • Update thread_integration_detector.h to check for IExecutor
  • Add integration tests for both isolated and combined builds
  • Update README with dependency configuration guidance
  • Create CMake preset for safe combined build

CMake Conflict Detection

# In logger_system/CMakeLists.txt
function(check_circular_dependency)
    # Check if thread_system has BUILD_WITH_LOGGER_SYSTEM enabled
    if(TARGET thread_system::thread_system)
        get_target_property(THREAD_DEFS thread_system::thread_system 
                           INTERFACE_COMPILE_DEFINITIONS)
        if(THREAD_DEFS MATCHES "BUILD_WITH_LOGGER_SYSTEM")
            message(WARNING 
                "Circular dependency risk: thread_system has BUILD_WITH_LOGGER_SYSTEM "
                "enabled while logger_system has LOGGER_HAS_THREAD_SYSTEM enabled. "
                "Recommend disabling one direction.")
        endif()
    endif()
endfunction()

Recommended Configuration Matrix

Use Case thread→logger logger→thread Notes
logger standalone OFF OFF Minimal build, internal thread
logger with thread_pool OFF ON Recommended - async I/O
thread with logging ON OFF For debugging thread_system
Full integration OFF ON Avoid reverse for production

Acceptance Criteria

  • CMake warns when bidirectional dependency detected
  • logger_system can use IExecutor instead of direct thread_system
  • Documentation clearly states recommended configuration
  • CI tests both isolated and combined builds
  • No compile error when only one direction enabled

Dependencies

  • Related: kcenon/thread_system#TBD (mirror issue)
  • Uses: common_system IExecutor interface

Parent Epic

Related Issues

Metadata

Metadata

Assignees

Labels

architectureArchitectural changes and designdependenciesDependency updates and managementpriority:highHigh priority issuerefactorCode refactoring without changing functionality

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions