hmon: add C++ interface to logic monitor#98
hmon: add C++ interface to logic monitor#98arkjedrz wants to merge 1 commit intoeclipse-score:mainfrom
Conversation
License Check Results🚀 The license check job ran with the Bazel command: bazel run --lockfile_mode=error //:license-checkStatus: Click to expand output |
|
The created documentation from the pull request is available at: docu-html |
There was a problem hiding this comment.
Pull request overview
This PR extends the health monitoring library with new monitor types (logic + heartbeat) and exposes them through the C++ API/FFI, while refactoring the Rust worker/evaluation plumbing and supervisor client selection to support multiple monitor kinds.
Changes:
- Add Rust
LogicMonitor+HeartbeatMonitorimplementations and integrate them intoHealthMonitorBuilder/HealthMonitor(including evaluation + error typing). - Add Rust FFI bindings and C++ wrappers/headers for heartbeat + logic monitors, and update the C++ health monitor API/tests accordingly.
- Refactor supervisor API client into a dedicated Rust module with feature-gated implementations and update the worker loop to pass a shared starting point into monitor evaluation.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/health_monitoring_lib/rust/worker.rs | Refactors evaluation loop for new error variants and passes hmon_starting_point into monitor evaluation; moves supervisor client trait out. |
| src/health_monitoring_lib/rust/tag.rs | Adds StateTag newtype for logic monitor state tagging and updates tag tests. |
| src/health_monitoring_lib/rust/supervisor_api_client/mod.rs | Introduces shared SupervisorAPIClient trait and feature-gated implementation modules. |
| src/health_monitoring_lib/rust/supervisor_api_client/stub_supervisor_api_client.rs | Adds stub supervisor client implementation. |
| src/health_monitoring_lib/rust/supervisor_api_client/score_supervisor_api_client.rs | Adds score supervisor client implementation (monitor_rs-based). |
| src/health_monitoring_lib/rust/logic/mod.rs | Adds logic monitor module exports and FFI module. |
| src/health_monitoring_lib/rust/logic/logic_monitor.rs | Implements LogicMonitor, builder, evaluation, and unit tests. |
| src/health_monitoring_lib/rust/logic/ffi.rs | Adds FFI API + tests for logic monitor builder/monitor operations. |
| src/health_monitoring_lib/rust/lib.rs | Integrates deadline/heartbeat/logic monitors into builder/health monitor, adds HealthMonitorError, and changes build()/start() to return Result. |
| src/health_monitoring_lib/rust/heartbeat/mod.rs | Adds heartbeat monitor module exports and FFI module. |
| src/health_monitoring_lib/rust/heartbeat/heartbeat_state.rs | Adds atomic packed heartbeat state representation + tests (incl. loom gating). |
| src/health_monitoring_lib/rust/heartbeat/heartbeat_monitor.rs | Implements HeartbeatMonitor, builder validation, evaluation logic, and extensive tests (incl. loom). |
| src/health_monitoring_lib/rust/heartbeat/ffi.rs | Adds FFI API + tests for heartbeat monitor builder and heartbeat calls. |
| src/health_monitoring_lib/rust/ffi.rs | Extends core FFI surface to add heartbeat/logic monitor support and map HealthMonitorError to FFICode. |
| src/health_monitoring_lib/rust/deadline/mod.rs | Re-exports DeadlineEvaluationError for typed evaluation errors. |
| src/health_monitoring_lib/rust/deadline/deadline_monitor.rs | Refactors deadline monitor to use HasEvalHandle, typed evaluation errors, and updated evaluator signature. |
| src/health_monitoring_lib/cpp/tests/health_monitor_test.cpp | Extends C++ integration test to construct/get/use heartbeat and logic monitors. |
| src/health_monitoring_lib/cpp/logic_monitor.cpp | Adds C++ wrapper implementation for logic monitor builder/monitor. |
| src/health_monitoring_lib/cpp/include/score/hm/tag.h | Adds default Tag ctor and introduces StateTag. |
| src/health_monitoring_lib/cpp/include/score/hm/logic/logic_monitor.h | Adds C++ public API for logic monitor builder/monitor. |
| src/health_monitoring_lib/cpp/include/score/hm/heartbeat/heartbeat_monitor.h | Adds C++ public API for heartbeat monitor builder/monitor. |
| src/health_monitoring_lib/cpp/include/score/hm/health_monitor.h | Extends C++ health monitor API to add/get heartbeat and logic monitors. |
| src/health_monitoring_lib/cpp/heartbeat_monitor.cpp | Adds C++ wrapper implementation for heartbeat monitor builder/monitor. |
| src/health_monitoring_lib/cpp/health_monitor.cpp | Extends C++ health monitor wrapper to add builder/get APIs for heartbeat + logic monitors. |
| src/health_monitoring_lib/Cargo.toml | Makes monitor_rs optional, adds loom target dep, and updates feature defaults. |
| src/health_monitoring_lib/BUILD | Adds new C++ sources/headers; adjusts Rust crate feature flags for Bazel targets/tests. |
| examples/rust_supervised_app/src/main.rs | Updates example to handle new Result returns for build() and start(). |
| Cargo.toml | Sets workspace default-members and configures unexpected_cfgs for cfg(loom). |
| Cargo.lock | Updates lockfile with new dependencies (loom + transitive crates). |
Comments suppressed due to low confidence (1)
src/health_monitoring_lib/cpp/include/score/hm/tag.h:39
Tagstoresdata_asconst char* const, which makes the pointer itself immutable after construction. Any FFI API that writes aStateTag/Taginto an out-parameter (e.g., aStateTag*passed to Rust) would end up mutating aconstsubobject, which is undefined behavior in C++. If tags are intended to be written/returned via out-params, change the field toconst char* data_(pointer-to-const data, but not const pointer) so the struct remains trivially writable.
/// Common string-based tag.
class Tag
{
public:
/// Create an empty tag.
Tag() : data_{nullptr}, length_{0} {}
/// Create a new tag from a C-style string.
template <size_t N>
explicit Tag(const char (&tag)[N]) : data_(tag), length_(N - 1)
{
}
private:
/// SAFETY: This has to be FFI compatible with the Rust side representation.
const char* const data_;
size_t length_;
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/health_monitoring_lib/rust/supervisor_api_client/score_supervisor_api_client.rs
Show resolved
Hide resolved
src/health_monitoring_lib/rust/supervisor_api_client/score_supervisor_api_client.rs
Show resolved
Hide resolved
7d6edc7 to
1df795e
Compare
1df795e to
9004e33
Compare
9004e33 to
0ad41b2
Compare
0ad41b2 to
1e7d813
Compare
src/health_monitoring_lib/cpp/include/score/hm/logic/logic_monitor.h
Outdated
Show resolved
Hide resolved
1e7d813 to
4d935eb
Compare
4d935eb to
96592df
Compare
96592df to
d8dbe32
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/health_monitoring_lib/cpp/include/score/hm/tag.h:39
Tag()initializesdata_tonullptr. On the Rust side, tags are formatted/hashed/compared usingslice::from_raw_parts(data, length), which requires a non-null pointer even whenlength == 0. Introducing default-constructed tags makes it easy to accidentally pass a null pointer over FFI and trigger UB in Rust. Consider defaultingdata_to a valid empty string pointer (""), and if tags are intended to be written by Rust (e.g., as out-params), avoidconston the stored pointer so mutation is well-defined in C++.
/// Create an empty tag.
Tag() : data_{nullptr}, length_{0} {}
/// Create a new tag from a C-style string.
template <size_t N>
explicit Tag(const char (&tag)[N]) : data_(tag), length_(N - 1)
{
}
private:
/// SAFETY: This has to be FFI compatible with the Rust side representation.
const char* const data_;
size_t length_;
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| { | ||
| public: | ||
| /// Create an empty tag. | ||
| Tag() : data_{nullptr}, length_{0} {} |
There was a problem hiding this comment.
Replaced with empty state tag in logic_monitor.cpp:84.
|
Look into Copilot issues too @arkjedrz |
d8dbe32 to
fe4dbfa
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/health_monitoring_lib/cpp/include/score/hm/tag.h:71
using Tag::Tag;no longer refers to the direct base class sinceTagis now a class template. As written, these derived tags likely won't inherit the constructor (and may fail to compile at call sites likeMonitorTag{"..."}). Update theusingdeclarations to reference the actual base specialization (e.g.,Tag<MonitorTag>,Tag<DeadlineTag>,Tag<StateTag>).
/// Monitor tag.
class MonitorTag : public Tag<MonitorTag>
{
public:
using Tag::Tag;
};
/// Deadline tag.
class DeadlineTag : public Tag<DeadlineTag>
{
public:
using Tag::Tag;
};
/// State tag.
class StateTag : public Tag<StateTag>
{
public:
using Tag::Tag;
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
9cd1470 to
e218b43
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| @@ -29,21 +31,40 @@ class Tag | |||
| { | |||
| } | |||
|
|
|||
| bool operator==(const T& other) const noexcept | |||
| { | |||
| std::string_view this_sv{data_, length_}; | |||
| std::string_view other_sv{other.data_, other.length_}; | |||
| return this_sv.compare(other_sv) == 0; | |||
| } | |||
|
|
|||
| bool operator!=(const T& other) const noexcept | |||
| { | |||
| return !(*this == other); | |||
| } | |||
|
|
|||
| private: | |||
| /// SAFETY: This has to be FFI compatible with the Rust side representation. | |||
| const char* const data_; | |||
| const char* data_; | |||
| size_t length_; | |||
| }; | |||
| class LogicMonitor final | ||
| { | ||
| public: | ||
| LogicMonitor(const LogicMonitor&) = delete; | ||
| LogicMonitor& operator=(const LogicMonitor&) = delete; | ||
|
|
||
| LogicMonitor(LogicMonitor&& other) noexcept = default; | ||
| LogicMonitor& operator=(LogicMonitor&& other) noexcept = default; | ||
|
|
||
| /// Perform transition to a new state. | ||
| /// On success, current state is returned. | ||
| score::cpp::expected<StateTag, Error> transition(const StateTag& state); | ||
|
|
||
| /// Current monitor state. | ||
| score::cpp::expected<StateTag, Error> state(); | ||
|
|
Add C++ interface to logic monitor.
e218b43 to
241480d
Compare
Add C++ interface to logic monitor.
Resolves #16