Goby3 3.4.0
2026.04.13
Loading...
Searching...
No Matches
health_monitor_thread.h
Go to the documentation of this file.
1// Copyright 2017-2026:
2// GobySoft, LLC (2013-)
3// Community contributors (see AUTHORS file)
4// File authors:
5// Toby Schneider <toby@gobysoft.org>
6//
7//
8// This file is part of the Goby Underwater Autonomy Project Libraries
9// ("The Goby Libraries").
10//
11// The Goby Libraries are free software: you can redistribute them and/or modify
12// them under the terms of the GNU Lesser General Public License as published by
13// the Free Software Foundation, either version 2.1 of the License, or
14// (at your option) any later version.
15//
16// The Goby Libraries are distributed in the hope that they will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public License
22// along with Goby. If not, see <http://www.gnu.org/licenses/>.
23
24#ifndef GOBY_MIDDLEWARE_CORONER_HEALTH_MONITOR_THREAD_H
25#define GOBY_MIDDLEWARE_CORONER_HEALTH_MONITOR_THREAD_H
26
30
32
33namespace goby
34{
35namespace middleware
36{
38{
39};
40
41template <typename ImplementationTag>
42class HealthMonitorThread : public SimpleThread<NullConfig, ImplementationTag>
43{
44 public:
46 : SimpleThread<NullConfig, ImplementationTag>(NullConfig(), 1.0 * boost::units::si::hertz)
47 {
48 // handle goby_coroner request
49 this->interprocess().template subscribe<groups::health_request, protobuf::HealthRequest>(
50 [this](const protobuf::HealthRequest& request)
51 {
52 this->interthread().template publish<groups::health_request>(
54 waiting_for_responses_ = true;
55 last_health_request_time_ = goby::time::SteadyClock::now();
56
57 std::shared_ptr<protobuf::ThreadHealth> our_response(new protobuf::ThreadHealth);
58 this->thread_health(*our_response);
59 child_responses_[our_response->uid()] = our_response;
60 });
61
62 // handle response from main thread
63 this->interthread().template subscribe<groups::health_response>(
64 [this](std::shared_ptr<const protobuf::ProcessHealth> response)
65 { health_response_ = *response; });
66
67 // handle response from child threads
68 this->interthread().template subscribe<groups::health_response>(
69 [this](std::shared_ptr<const protobuf::ThreadHealth> response)
70 { child_responses_[response->uid()] = response; });
71 }
72
73 private:
74 void loop() override
75 {
76 if (waiting_for_responses_ &&
77 goby::time::SteadyClock::now() > last_health_request_time_ + health_request_timeout_)
78 {
79 goby::middleware::protobuf::HealthState health_state = health_response_.main().state();
80
81 // overwrite any child responses we got
82 for (auto& thread_health : *health_response_.mutable_main()->mutable_child())
83 {
84 if (child_responses_.count(thread_health.uid()))
85 thread_health = *child_responses_.at(thread_health.uid());
86
87 if (thread_health.state() > health_state)
88 health_state = thread_health.state();
89 }
90
91 health_response_.mutable_main()->set_state(health_state);
92
93 if (health_response_.IsInitialized())
94 this->interprocess().template publish<groups::health_response>(health_response_);
95
96 waiting_for_responses_ = false;
97 child_responses_.clear();
98 health_response_.Clear();
99 }
100 }
101 void initialize() override { this->set_name("health_monitor"); }
102
103 private:
104 protobuf::ProcessHealth health_response_;
105 // uid to response
106 std::map<int, std::shared_ptr<const protobuf::ThreadHealth>> child_responses_;
107 goby::time::SteadyClock::time_point last_health_request_time_;
108 const goby::time::SteadyClock::duration health_request_timeout_{std::chrono::seconds(1)};
109 bool waiting_for_responses_{false};
110};
111
112} // namespace middleware
113} // namespace goby
114
115#endif
Implements Thread for a three layer middleware setup ([ intervehicle [ interprocess [ interthread ] ]...
InterThreadTransporter & interthread()
Access the transporter on the interthread layer (this is the innermost transporter)
InterProcessForwarder< InterThreadTransporter, ImplementationTag > & interprocess()
Access the transporter on the interprocess layer (which wraps interthread)
void set_name(const std::string &name)
Definition thread.h:151
void thread_health(goby::middleware::protobuf::ThreadHealth &health)
Definition thread.h:223
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
const ::goby::middleware::protobuf::ThreadHealth & main() const
::goby::middleware::protobuf::ThreadHealth * mutable_main()
void set_state(::goby::middleware::protobuf::HealthState value)
::goby::middleware::protobuf::HealthState state() const
The global namespace for the Goby project.
std::chrono::time_point< SteadyClock > time_point
static time_point now() noexcept
Returns the current steady time unless SimulatorSettings::using_sim_time == true in which case a simu...
std::chrono::microseconds duration
Duration type.