Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions examples/cpp_supervised_app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
#include <sys/prctl.h>
#endif

#include <score/mw/health/common.h>
#include <score/mw/health/health_monitor_builder.h>
#include <score/mw/lifecycle/report_running.h>
#include <score/mw/log/rust/stdout_logger_init.h>
#include <score/mw/health/common.h>
#include <score/mw/health/health_monitor.h>
#include <thread>

/// @brief CLI configuration options for the demo_application process
Expand Down Expand Up @@ -114,56 +114,61 @@ int main(int argc, char** argv)
using namespace score::mw::health;

auto builder_mon =
deadline::DeadlineMonitorBuilder()
.add_deadline(DeadlineTag("deadline_1"),
TimeRange(std::chrono::milliseconds(50), std::chrono::milliseconds(150)))
.add_deadline(DeadlineTag("deadline_2"),
TimeRange(std::chrono::milliseconds(2),
std::chrono::milliseconds(20))); // Not used, only shows
// that multiple deadlines can be added

MonitorTag ident("monitor");
DeadlineMonitorConfiguration()
.AddDeadline(Tag("deadline_1"), TimeRange(std::chrono::milliseconds(50), std::chrono::milliseconds(150)))
.AddDeadline(Tag("deadline_2"),
TimeRange(std::chrono::milliseconds(2),
std::chrono::milliseconds(20))); // Not used, only shows
// that multiple deadlines can be added

{
auto hm_res = HealthMonitorBuilder()
.add_deadline_monitor(ident, std::move(builder_mon))
.with_internal_processing_cycle(std::chrono::milliseconds(50))
.with_supervisor_api_cycle(std::chrono::milliseconds(50))
.build();
auto hm_res = HealthMonitorBuilder::Create()
->AddDeadlineMonitor(Tag("monitor"), std::move(builder_mon))
.WithInternalProcessingCycle(std::chrono::milliseconds(50))
.WithSupervisorApiCycle(std::chrono::milliseconds(50))
.Build();
if (!hm_res.has_value())
{
std::cerr << "Failed to build health monitor" << std::endl;
return EXIT_FAILURE;
}
auto hm = std::move(*hm_res);

auto deadline_monitor_res = hm.get_deadline_monitor(ident);
auto deadline_monitor_res = hm->GetDeadlineMonitor(Tag("monitor"));
if (!deadline_monitor_res.has_value())
{
std::cerr << "Failed to get deadline monitor" << std::endl;
return EXIT_FAILURE;
}

hm.start();
hm->Start();

score::mw::lifecycle::report_running();

auto deadline_mon = std::move(*deadline_monitor_res);

auto deadline_res = deadline_mon.get_deadline(DeadlineTag("deadline_1"));
auto deadline_result = deadline_mon->GetDeadline(Tag("deadline_1"));
if (!deadline_result.has_value())
{
std::cerr << "Failed to get deadline" << std::endl;
return EXIT_FAILURE;
}
auto deadline = std::move(*deadline_result);

while (!exitRequested)
{
if (stopReportingCheckpoints.load())
{
break;
}

auto deadline_guard = deadline_res.value().start();
{
DeadlineGuard deadline_guard(*deadline);

std::this_thread::sleep_for(std::chrono::milliseconds(config->delayInMs));
std::this_thread::sleep_for(std::chrono::milliseconds(config->delayInMs));

// deadline_guard.stop(); // Optional, will be stopped automatically when going out of scope - this way we
// dont check Result from start() call
// Deadline is automatically stopped when deadline_guard goes out of scope.
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions score/health_monitor/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@rules_cc//cc:defs.bzl", "cc_library")

alias(
name = "health_monitoring_cc",
actual = "//score/health_monitor/src/cpp:health_monitoring_cc",
visibility = ["//visibility:public"],
)

alias(
name = "health_monitoring_cc_interface",
actual = "//score/health_monitor/src/cpp:health_monitoring_cc_interface",
visibility = ["//visibility:public"],
)

alias(
name = "health_monitoring_cc_mock",
actual = "//score/health_monitor/src/cpp:health_monitoring_cc_mock",
visibility = ["//visibility:public"],
)

alias(
name = "health_monitoring_rust",
actual = "//score/health_monitor/src/rust:health_monitoring_lib",
Expand Down
62 changes: 35 additions & 27 deletions score/health_monitor/src/cpp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,42 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
load("@score_baselibs//:bazel/unit_tests.bzl", "cc_gtest_unit_test")

cc_library(
name = "tag",
hdrs = ["tag.h"],
include_prefix = "score/mw/health",
strip_include_prefix = "/score/health_monitor/src/cpp",
visibility = ["//visibility:public"],
)

cc_library(
name = "common",
srcs = ["common.cpp"],
hdrs = ["common.h"],
name = "health_monitoring_cc_interface",
hdrs = [
"common.h",
"deadline_monitor.h",
"health_monitor.h",
"health_monitor_builder.h",
"heartbeat_monitor.h",
"logic_monitor.h",
],
include_prefix = "score/mw/health",
strip_include_prefix = "/score/health_monitor/src/cpp",
visibility = ["//visibility:public"],
deps = ["@score_baselibs//score/language/futurecpp"],
visibility = ["//score/health_monitor:__subpackages__"],
deps = [
"@score_baselibs//score/language/futurecpp",
"@score_baselibs//score/result",
],
)

cc_library(
name = "health_monitor",
srcs = ["health_monitor.cpp"],
hdrs = ["health_monitor.h"],
name = "health_monitoring_cc_mock",
srcs = ["health_monitor_mocks.cpp"],
hdrs = ["health_monitor_mocks.h"],
include_prefix = "score/mw/health",
strip_include_prefix = "/score/health_monitor/src/cpp",
visibility = ["//score:__subpackages__"],
visibility = ["//score/health_monitor:__pkg__"],
deps = [
":common",
":tag",
"//score/health_monitor/src/cpp/deadline:deadline_monitor",
"//score/health_monitor/src/cpp/details:thread",
"//score/health_monitor/src/cpp/heartbeat:heartbeat_monitor",
"//score/health_monitor/src/cpp/logic:logic_monitor",
":health_monitoring_cc_interface",
"@googletest//:gtest",
],
)

cc_library(
name = "health_monitoring_cc",
visibility = ["//score/health_monitor:__pkg__"],
deps = [
"//score/health_monitor/src/cpp:health_monitor",
"//score/health_monitor/src/cpp/details:health_monitor_impl",
"//score/health_monitor/src/rust:health_monitoring_lib_ffi",
],
)
Expand All @@ -62,7 +59,7 @@ cc_library(
name = "health_monitoring_cc_stub_supervisor",
visibility = ["//score/health_monitor/src/cpp:__pkg__"],
deps = [
"//score/health_monitor/src/cpp:health_monitor",
"//score/health_monitor/src/cpp/details:health_monitor_impl",
"//score/health_monitor/src/rust:health_monitoring_lib_stub_supervisor",
],
)
Expand All @@ -81,7 +78,7 @@ cc_gtest_unit_test(
"@platforms//os:linux": [],
}),
deps = [
"//score/health_monitor/src/cpp:health_monitoring_cc_stub_supervisor",
":health_monitoring_cc_stub_supervisor",
"//score/health_monitor/src/cpp/details:log_init",
],
)
Expand All @@ -96,7 +93,18 @@ cc_gtest_unit_test(
"@platforms//os:linux": [],
}),
deps = [
"//score/health_monitor/src/cpp:health_monitoring_cc_stub_supervisor",
":health_monitoring_cc_stub_supervisor",
"//score/health_monitor/src/cpp/details:log_init",
],
)

cc_gtest_unit_test(
name = "cpp_mock_tests",
srcs = [
"tests/mock_test.cpp",
],
deps = [
":health_monitoring_cc_interface",
":health_monitoring_cc_mock",
],
)
92 changes: 32 additions & 60 deletions score/health_monitor/src/cpp/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,76 +15,48 @@

#include <score/assert.hpp>
#include <chrono>
#include <optional>
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>

namespace score::mw::health
{

/// FFI internal helpers
namespace internal
{

/// Internal success representation.
constexpr int kSuccess = 0;

/// Internal return code.
using FFICode = uint8_t;

/// Opaque handle type for Rust managed object
using FFIHandle = void*;

/// Droppable wrapper that denotes that the object can be dropped by Rust side
template <typename T>
class RustDroppable
/// Compile-time string tag. Only constructible from string literals (static storage duration).
/// Pointers are always valid — no lifetime management needed.
class Tag
{
public:
virtual ~RustDroppable() = default;

protected:
/// Marks object as no longer managed by C++ side, releasing handle to be passed to Rust side for dropping
std::optional<FFIHandle> drop_by_rust()
template <size_t N>
constexpr explicit Tag(const char (&literal)[N]) : data_(literal), length_(N - 1)
{
return static_cast<T*>(this)->_drop_by_rust_impl();
}
};

/// Wrapper for FFIHandle that ensures proper dropping via provided drop function
class DroppableFFIHandle
{
public:
using DropFn = internal::FFICode (*)(FFIHandle);

DroppableFFIHandle(FFIHandle handle, DropFn drop_fn);

DroppableFFIHandle(const DroppableFFIHandle&) = delete;
DroppableFFIHandle& operator=(const DroppableFFIHandle&) = delete;

DroppableFFIHandle(DroppableFFIHandle&& other) noexcept;
DroppableFFIHandle& operator=(DroppableFFIHandle&& other) noexcept;

/// Get the underlying FFI handle if it was not dropped before
std::optional<FFIHandle> as_rust_handle() const;

/// Marks object as no longer managed by C++ side, releasing handle to be passed to Rust side for dropping
std::optional<FFIHandle> drop_by_rust();
constexpr bool operator==(const Tag& other) const noexcept
{
return std::string_view{data_, length_} == std::string_view{other.data_, other.length_};
}

virtual ~DroppableFFIHandle();
constexpr bool operator!=(const Tag& other) const noexcept
{
return !(*this == other);
}

private:
FFIHandle handle_;
DropFn drop_fn_;
const char* data_;
size_t length_;
};

} // namespace internal
static_assert(std::is_standard_layout_v<Tag>, "Tag must be standard-layout for FFI compatibility");

enum class Error : internal::FFICode
enum class Error : uint8_t
{
NullParameter = internal::kSuccess + 1,
NotFound,
AlreadyExists,
InvalidArgument,
WrongState,
Failed
kNotFound = 2,
kAlreadyExists,
kInvalidArgument,
kWrongState,
kFailed
};

///
Expand All @@ -98,19 +70,19 @@ class TimeRange
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(min_ms_ <= max_ms_);
}

uint32_t min_ms() const
std::chrono::milliseconds Min() const
{
return min_ms_.count();
return min_ms_;
}

uint32_t max_ms() const
std::chrono::milliseconds Max() const
{
return max_ms_.count();
return max_ms_;
}

private:
const std::chrono::milliseconds min_ms_;
const std::chrono::milliseconds max_ms_;
std::chrono::milliseconds min_ms_;
std::chrono::milliseconds max_ms_;
};

} // namespace score::mw::health
Expand Down
28 changes: 0 additions & 28 deletions score/health_monitor/src/cpp/deadline/BUILD

This file was deleted.

Loading
Loading