Skip to content

Update controller selection #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Update controller selection #22

wants to merge 8 commits into from

Conversation

sonndinh
Copy link
Member

@sonndinh sonndinh commented Jun 27, 2025

  • Problem:
    Power device relies on the Heartbeat messages from microgrid controllers to determine its active controller. Heartbeat's period is 1 second. If a Heartbeat is not received from a selected (or active) controller within 3 seconds since the last Heartbeat, the selected controller is considered disappearing and the power device starts a process to select a new selected controller. Current implementation schedule (or reschedule if the timer already exists) a timer with expiration of 3 seconds to detect missed Heartbeats. The default timer queue used by ACE_Reactor, ACE_Timer_Heap, is having an issue with this setup: missed Heartbeat timers fire even though the Heartbeats are still received from the active controller. This happens around time when the timer Id returned by ACE_Timer_Heap has reached its limit and wrapped around.

  • Solution:

  1. Use ACE_Timer_Hash for the ACE reactor -- ACE_Timer_Hash doesn't seem to have the same issue.
  2. Support a separate reactor instance for the controller selector to isolate it from the reactor for Handshaking. This can help with debugging the controller selector.
  • Misc. changes:
  1. Add tms::ActiveMicrogridControllerState topic to power devices that gives the CLI updates on their selected controller
  2. Improve printing format for the list of power devices in CLI and add information for each device's selected controller

@sonndinh sonndinh marked this pull request as ready for review July 2, 2025 16:32
@@ -328,6 +370,19 @@ void CLIClient::run()
thr.join();
}

void CLIClient::set_active_controller(const tms::Identity& device_id,
const OPENDDS_OPTIONAL_NS::optional<tms::Identity>& master_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option here would be to require that we build with std::optional, so the macro wouldn't be needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already require C++17, so we should have it.

const OPENDDS_OPTIONAL_NS::optional<tms::Identity>& master_id)
{
std::lock_guard<std::mutex> guard(active_controllers_m_);
if (master_id.has_value()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +10 to +14
: TimerHandler(reactor)
, device_id_(device_id)
{
if (!reactor) {
reactor_ = new ACE_Reactor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the TimerHandler constructor (in the future) does anything with its parameter besides just assigning to reactor_ then this could lead to an inconsistency.

One option is to make the TimerHandler (or some other class) take charge of managing the reactor and timer queue, along with the own_reactor_ bit, so it's done in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants