SMACC2
Loading...
Searching...
No Matches
cl_gcalcli::CpGcalcliConnection Class Reference

Component that manages gcalcli connection health. More...

#include <cp_gcalcli_connection.hpp>

Inheritance diagram for cl_gcalcli::CpGcalcliConnection:
Inheritance graph
Collaboration diagram for cl_gcalcli::CpGcalcliConnection:
Collaboration graph

Public Member Functions

 CpGcalcliConnection ()
 
virtual ~CpGcalcliConnection ()=default
 
void onInitialize () override
 
void configure (const GcalcliConfig &config)
 Configure the gcalcli connection parameters.
 
ConnectionState getConnectionState () const
 Get current connection state.
 
bool isConnected () const
 Check if connected to Google Calendar.
 
bool checkConnection ()
 Manually trigger a connection check.
 
void restartConnection ()
 Restart connection after failure.
 
smacc2::client_core_components::SubprocessResult executeGcalcli (const std::string &args, int timeout_ms=30000)
 Execute a gcalcli command.
 
const GcalcliConfiggetConfig () const
 Get the gcalcli configuration.
 
template<typename T >
smacc2::SmaccSignalConnection onConnectionLost (void(T::*callback)(), T *object)
 
template<typename T >
smacc2::SmaccSignalConnection onConnectionRestored (void(T::*callback)(), T *object)
 
template<typename T >
smacc2::SmaccSignalConnection onAuthenticationRequired (void(T::*callback)(), T *object)
 
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 Template method for type-safe event posting setup.
 
- Public Member Functions inherited from smacc2::ISmaccComponent
 ISmaccComponent ()
 
virtual ~ISmaccComponent ()
 
virtual std::string getName () const
 
- Public Member Functions inherited from smacc2::ISmaccUpdatable
 ISmaccUpdatable ()
 
 ISmaccUpdatable (rclcpp::Duration duration)
 
void executeUpdate (rclcpp::Node::SharedPtr node)
 
void setUpdatePeriod (rclcpp::Duration duration)
 

Public Attributes

smacc2::SmaccSignal< void()> onConnectionLost_
 
smacc2::SmaccSignal< void()> onConnectionRestored_
 
smacc2::SmaccSignal< void()> onAuthenticationRequired_
 
std::function< void()> postConnectionLostEvent_
 
std::function< void()> postConnectionRestoredEvent_
 
std::function< void()> postAuthenticationRequiredEvent_
 

Protected Member Functions

void update () override
 Periodic update for heartbeat (called by SignalDetector)
 
- Protected Member Functions inherited from smacc2::ISmaccComponent
template<typename TOrthogonal , typename TClient >
void onComponentInitialization ()
 
template<typename EventType >
void postEvent (const EventType &ev)
 
template<typename EventType >
void postEvent ()
 
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
template<typename TComponent >
void requiresComponent (TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TComponent >
void requiresComponent (std::string name, TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TClient >
void requiresClient (TClient *&requiredClientStorage)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingComponent (TArgs... targs)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingNamedComponent (std::string name, TArgs... targs)
 
rclcpp::Node::SharedPtr getNode ()
 
rclcpp::Logger getLogger () const
 
ISmaccStateMachinegetStateMachine ()
 
- Protected Member Functions inherited from smacc2::ISmaccUpdatable

Private Member Functions

void performHeartbeat ()
 Perform the heartbeat check.
 
void handleConnectionStateChange (bool success, const std::string &output)
 Handle connection state change.
 
bool isAuthenticationError (const std::string &output) const
 Check if output indicates authentication failure.
 

Private Attributes

GcalcliConfig config_
 
ConnectionState connection_state_
 
int consecutive_failures_
 
bool initialized_
 
std::chrono::steady_clock::time_point last_heartbeat_time_
 
smacc2::client_core_components::CpSubprocessExecutorsubprocess_executor_
 
std::mutex state_mutex_
 

Additional Inherited Members

- Protected Attributes inherited from smacc2::ISmaccComponent
ISmaccStateMachinestateMachine_
 
ISmaccClientowner_
 

Detailed Description

Component that manages gcalcli connection health.

This component monitors the connection to Google Calendar via gcalcli. It performs periodic heartbeat checks using "gcalcli list" and tracks consecutive failures. After max_consecutive_failures, it emits EvConnectionLost events.

The component uses CpSubprocessExecutor from smacc2 core for command execution.

Definition at line 42 of file cp_gcalcli_connection.hpp.

Constructor & Destructor Documentation

◆ CpGcalcliConnection()

cl_gcalcli::CpGcalcliConnection::CpGcalcliConnection ( )

◆ ~CpGcalcliConnection()

virtual cl_gcalcli::CpGcalcliConnection::~CpGcalcliConnection ( )
virtualdefault

Member Function Documentation

◆ checkConnection()

bool cl_gcalcli::CpGcalcliConnection::checkConnection ( )

Manually trigger a connection check.

Returns
true if connection succeeded

Definition at line 69 of file cp_gcalcli_connection.cpp.

70{
72 {
73 RCLCPP_ERROR(getLogger(), "[CpGcalcliConnection] Subprocess executor not available");
74 return false;
75 }
76
77 // Use "gcalcli list" as a lightweight connection test
78 auto result = executeGcalcli("list", 10000);
79
80 bool success = (result.exit_code == 0 && !result.timed_out);
81 handleConnectionStateChange(success, result.stdout_output);
82
83 return success;
84}
smacc2::client_core_components::SubprocessResult executeGcalcli(const std::string &args, int timeout_ms=30000)
Execute a gcalcli command.
void handleConnectionStateChange(bool success, const std::string &output)
Handle connection state change.
rclcpp::Logger getLogger() const

References executeGcalcli(), smacc2::ISmaccComponent::getLogger(), handleConnectionStateChange(), and subprocess_executor_.

Here is the call graph for this function:

◆ configure()

void cl_gcalcli::CpGcalcliConnection::configure ( const GcalcliConfig & config)

Configure the gcalcli connection parameters.

Definition at line 50 of file cp_gcalcli_connection.cpp.

51{
52 std::lock_guard<std::mutex> lock(state_mutex_);
53 config_ = config;
54 RCLCPP_DEBUG(getLogger(), "[CpGcalcliConnection] Configuration updated");
55}

References config_, smacc2::ISmaccComponent::getLogger(), and state_mutex_.

Here is the call graph for this function:

◆ executeGcalcli()

smacc2::client_core_components::SubprocessResult cl_gcalcli::CpGcalcliConnection::executeGcalcli ( const std::string & args,
int timeout_ms = 30000 )

Execute a gcalcli command.

Parameters
argsCommand arguments (e.g., "agenda --tsv")
timeout_msCommand timeout in milliseconds
Returns
SubprocessResult with output and exit code

Definition at line 96 of file cp_gcalcli_connection.cpp.

98{
100 {
102 error_result.exit_code = -1;
103 error_result.stderr_output = "Subprocess executor not available";
104 error_result.timed_out = false;
105 return error_result;
106 }
107
108 // Build the full command
109 std::string command = config_.gcalcli_path;
110
111 // Add config folder if specified
112 if (config_.config_folder.has_value())
113 {
114 command += " --config-folder \"" + config_.config_folder.value() + "\"";
115 }
116
117 // Add calendars if specified
118 for (const auto & calendar : config_.calendars)
119 {
120 command += " --calendar \"" + calendar + "\"";
121 }
122
123 // Add the command arguments
124 command += " " + args;
125
126 RCLCPP_DEBUG(getLogger(), "[CpGcalcliConnection] Executing: %s", command.c_str());
127
128 return subprocess_executor_->executeCommand(command, timeout_ms);
129}
SubprocessResult executeCommand(const std::string &command, int timeout_ms=30000)
Execute a command synchronously.
std::string gcalcli_path
Path to gcalcli executable (default: "gcalcli" from PATH)
Definition types.hpp:104
std::vector< std::string > calendars
Calendars to monitor (empty = all calendars)
Definition types.hpp:110
std::optional< std::string > config_folder
Optional config folder for gcalcli (if not using default)
Definition types.hpp:107

References cl_gcalcli::GcalcliConfig::calendars, config_, cl_gcalcli::GcalcliConfig::config_folder, smacc2::client_core_components::CpSubprocessExecutor::executeCommand(), smacc2::client_core_components::SubprocessResult::exit_code, cl_gcalcli::GcalcliConfig::gcalcli_path, smacc2::ISmaccComponent::getLogger(), smacc2::client_core_components::SubprocessResult::stderr_output, subprocess_executor_, and smacc2::client_core_components::SubprocessResult::timed_out.

Referenced by checkConnection(), cl_gcalcli::CbQuickAdd::onEntry(), performHeartbeat(), and cl_gcalcli::CpCalendarPoller::refreshAgenda().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getConfig()

const GcalcliConfig & cl_gcalcli::CpGcalcliConnection::getConfig ( ) const
inline

Get the gcalcli configuration.

Definition at line 88 of file cp_gcalcli_connection.hpp.

88{ return config_; }

References config_.

Referenced by cl_gcalcli::CpCalendarPoller::refreshAgenda(), and cl_gcalcli::CpCalendarPoller::update().

Here is the caller graph for this function:

◆ getConnectionState()

ConnectionState cl_gcalcli::CpGcalcliConnection::getConnectionState ( ) const

Get current connection state.

Definition at line 57 of file cp_gcalcli_connection.cpp.

58{
59 std::lock_guard<std::mutex> lock(state_mutex_);
60 return connection_state_;
61}

References connection_state_, and state_mutex_.

◆ handleConnectionStateChange()

void cl_gcalcli::CpGcalcliConnection::handleConnectionStateChange ( bool success,
const std::string & output )
private

Handle connection state change.

Definition at line 158 of file cp_gcalcli_connection.cpp.

159{
160 std::lock_guard<std::mutex> lock(state_mutex_);
161
162 ConnectionState previous_state = connection_state_;
163
164 if (success)
165 {
167
169 {
171 RCLCPP_INFO(getLogger(), "[CpGcalcliConnection] Connection established");
172
173 if (
174 previous_state == ConnectionState::ERROR || previous_state == ConnectionState::DISCONNECTED)
175 {
178 {
180 }
181 }
182 }
183 }
184 else
185 {
187
188 // Check if this is an authentication error
189 if (isAuthenticationError(output))
190 {
192 RCLCPP_WARN(getLogger(), "[CpGcalcliConnection] Authentication required");
193
196 {
198 }
199 }
201 {
203 {
205 RCLCPP_ERROR(
206 getLogger(), "[CpGcalcliConnection] Connection lost after %d consecutive failures",
208
211 {
213 }
214 }
215 }
216 else
217 {
218 RCLCPP_WARN(
219 getLogger(), "[CpGcalcliConnection] Connection check failed (%d/%d)", consecutive_failures_,
221 }
222 }
223}
std::function< void()> postConnectionLostEvent_
bool isAuthenticationError(const std::string &output) const
Check if output indicates authentication failure.
smacc2::SmaccSignal< void()> onConnectionLost_
smacc2::SmaccSignal< void()> onAuthenticationRequired_
std::function< void()> postAuthenticationRequiredEvent_
smacc2::SmaccSignal< void()> onConnectionRestored_
std::function< void()> postConnectionRestoredEvent_
int max_consecutive_failures
Number of consecutive failures before connection is considered lost.
Definition types.hpp:122

References cl_gcalcli::AUTHENTICATING, config_, cl_gcalcli::CONNECTED, connection_state_, consecutive_failures_, cl_gcalcli::DISCONNECTED, cl_gcalcli::ERROR, smacc2::ISmaccComponent::getLogger(), isAuthenticationError(), cl_gcalcli::GcalcliConfig::max_consecutive_failures, onAuthenticationRequired_, onConnectionLost_, onConnectionRestored_, postAuthenticationRequiredEvent_, postConnectionLostEvent_, postConnectionRestoredEvent_, and state_mutex_.

Referenced by checkConnection(), and performHeartbeat().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isAuthenticationError()

bool cl_gcalcli::CpGcalcliConnection::isAuthenticationError ( const std::string & output) const
private

Check if output indicates authentication failure.

Definition at line 225 of file cp_gcalcli_connection.cpp.

226{
227 // Check for common gcalcli authentication error patterns
228 return output.find("Authentication") != std::string::npos ||
229 output.find("authorization") != std::string::npos ||
230 output.find("oauth") != std::string::npos ||
231 output.find("credentials") != std::string::npos ||
232 output.find("token") != std::string::npos;
233}

Referenced by handleConnectionStateChange().

Here is the caller graph for this function:

◆ isConnected()

bool cl_gcalcli::CpGcalcliConnection::isConnected ( ) const

Check if connected to Google Calendar.

Definition at line 63 of file cp_gcalcli_connection.cpp.

64{
65 std::lock_guard<std::mutex> lock(state_mutex_);
67}

References cl_gcalcli::CONNECTED, connection_state_, and state_mutex_.

Referenced by cl_gcalcli::CpCalendarPoller::refreshAgenda(), and cl_gcalcli::CpCalendarPoller::update().

Here is the caller graph for this function:

◆ onAuthenticationRequired()

template<typename T >
smacc2::SmaccSignalConnection cl_gcalcli::CpGcalcliConnection::onAuthenticationRequired ( void(T::* callback )(),
T * object )
inline

Definition at line 109 of file cp_gcalcli_connection.hpp.

110 {
112 onAuthenticationRequired_, callback, object);
113 }
ISmaccStateMachine * getStateMachine()
smacc2::SmaccSignalConnection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)

References smacc2::ISmaccStateMachine::createSignalConnection(), and smacc2::ISmaccComponent::getStateMachine().

Here is the call graph for this function:

◆ onConnectionLost()

template<typename T >
smacc2::SmaccSignalConnection cl_gcalcli::CpGcalcliConnection::onConnectionLost ( void(T::* callback )(),
T * object )
inline

Definition at line 97 of file cp_gcalcli_connection.hpp.

98 {
99 return this->getStateMachine()->createSignalConnection(onConnectionLost_, callback, object);
100 }

References smacc2::ISmaccStateMachine::createSignalConnection(), and smacc2::ISmaccComponent::getStateMachine().

Referenced by cl_gcalcli::CbMonitorConnection::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onConnectionRestored()

template<typename T >
smacc2::SmaccSignalConnection cl_gcalcli::CpGcalcliConnection::onConnectionRestored ( void(T::* callback )(),
T * object )
inline

Definition at line 103 of file cp_gcalcli_connection.hpp.

104 {
105 return this->getStateMachine()->createSignalConnection(onConnectionRestored_, callback, object);
106 }

References smacc2::ISmaccStateMachine::createSignalConnection(), and smacc2::ISmaccComponent::getStateMachine().

Referenced by cl_gcalcli::CbMonitorConnection::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onInitialize()

void cl_gcalcli::CpGcalcliConnection::onInitialize ( )
overridevirtual

Reimplemented from smacc2::ISmaccComponent.

Definition at line 28 of file cp_gcalcli_connection.cpp.

29{
30 if (!initialized_)
31 {
32 // Get the subprocess executor component
34
35 if (subprocess_executor_ == nullptr)
36 {
37 RCLCPP_ERROR(getLogger(), "[CpGcalcliConnection] CpSubprocessExecutor component not found!");
38 return;
39 }
40
41 last_heartbeat_time_ = std::chrono::steady_clock::now();
42 initialized_ = true;
43
44 RCLCPP_INFO(
45 getLogger(), "[CpGcalcliConnection] Initialized with gcalcli path: %s",
46 config_.gcalcli_path.c_str());
47 }
48}
std::chrono::steady_clock::time_point last_heartbeat_time_
void requiresComponent(TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)

References config_, cl_gcalcli::GcalcliConfig::gcalcli_path, smacc2::ISmaccComponent::getLogger(), initialized_, last_heartbeat_time_, smacc2::ISmaccComponent::requiresComponent(), and subprocess_executor_.

Here is the call graph for this function:

◆ onStateOrthogonalAllocation()

template<typename TOrthogonal , typename TSourceObject >
void cl_gcalcli::CpGcalcliConnection::onStateOrthogonalAllocation ( )
inline

Template method for type-safe event posting setup.

Definition at line 124 of file cp_gcalcli_connection.hpp.

References postConnectionLostEvent_, and smacc2::ISmaccComponent::postEvent().

Here is the call graph for this function:

◆ performHeartbeat()

void cl_gcalcli::CpGcalcliConnection::performHeartbeat ( )
private

Perform the heartbeat check.

Definition at line 148 of file cp_gcalcli_connection.cpp.

149{
150 RCLCPP_DEBUG(getLogger(), "[CpGcalcliConnection] Performing heartbeat check...");
151
152 auto result = executeGcalcli("list", 10000);
153
154 bool success = (result.exit_code == 0 && !result.timed_out);
155 handleConnectionStateChange(success, result.stdout_output);
156}

References executeGcalcli(), smacc2::ISmaccComponent::getLogger(), and handleConnectionStateChange().

Referenced by update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restartConnection()

void cl_gcalcli::CpGcalcliConnection::restartConnection ( )

Restart connection after failure.

Definition at line 86 of file cp_gcalcli_connection.cpp.

87{
88 std::lock_guard<std::mutex> lock(state_mutex_);
89
90 RCLCPP_INFO(getLogger(), "[CpGcalcliConnection] Restarting connection...");
91
94}

References connection_state_, consecutive_failures_, cl_gcalcli::DISCONNECTED, smacc2::ISmaccComponent::getLogger(), and state_mutex_.

Here is the call graph for this function:

◆ update()

void cl_gcalcli::CpGcalcliConnection::update ( )
overrideprotectedvirtual

Periodic update for heartbeat (called by SignalDetector)

Implements smacc2::ISmaccUpdatable.

Definition at line 131 of file cp_gcalcli_connection.cpp.

132{
134 {
135 return;
136 }
137
138 auto now = std::chrono::steady_clock::now();
139 auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - last_heartbeat_time_);
140
141 if (elapsed >= config_.heartbeat_interval)
142 {
145 }
146}
void performHeartbeat()
Perform the heartbeat check.
std::chrono::seconds heartbeat_interval
How often to check connection health (heartbeat)
Definition types.hpp:116

References config_, cl_gcalcli::GcalcliConfig::heartbeat_interval, initialized_, last_heartbeat_time_, performHeartbeat(), and subprocess_executor_.

Here is the call graph for this function:

Member Data Documentation

◆ config_

GcalcliConfig cl_gcalcli::CpGcalcliConnection::config_
private

◆ connection_state_

ConnectionState cl_gcalcli::CpGcalcliConnection::connection_state_
private

◆ consecutive_failures_

int cl_gcalcli::CpGcalcliConnection::consecutive_failures_
private

Definition at line 160 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange(), and restartConnection().

◆ initialized_

bool cl_gcalcli::CpGcalcliConnection::initialized_
private

Definition at line 161 of file cp_gcalcli_connection.hpp.

Referenced by onInitialize(), and update().

◆ last_heartbeat_time_

std::chrono::steady_clock::time_point cl_gcalcli::CpGcalcliConnection::last_heartbeat_time_
private

Definition at line 163 of file cp_gcalcli_connection.hpp.

Referenced by onInitialize(), and update().

◆ onAuthenticationRequired_

smacc2::SmaccSignal<void()> cl_gcalcli::CpGcalcliConnection::onAuthenticationRequired_

Definition at line 93 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange().

◆ onConnectionLost_

smacc2::SmaccSignal<void()> cl_gcalcli::CpGcalcliConnection::onConnectionLost_

Definition at line 91 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange().

◆ onConnectionRestored_

smacc2::SmaccSignal<void()> cl_gcalcli::CpGcalcliConnection::onConnectionRestored_

Definition at line 92 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange().

◆ postAuthenticationRequiredEvent_

std::function<void()> cl_gcalcli::CpGcalcliConnection::postAuthenticationRequiredEvent_

Definition at line 118 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange().

◆ postConnectionLostEvent_

std::function<void()> cl_gcalcli::CpGcalcliConnection::postConnectionLostEvent_

◆ postConnectionRestoredEvent_

std::function<void()> cl_gcalcli::CpGcalcliConnection::postConnectionRestoredEvent_

Definition at line 117 of file cp_gcalcli_connection.hpp.

Referenced by handleConnectionStateChange().

◆ state_mutex_

std::mutex cl_gcalcli::CpGcalcliConnection::state_mutex_
mutableprivate

◆ subprocess_executor_

smacc2::client_core_components::CpSubprocessExecutor* cl_gcalcli::CpGcalcliConnection::subprocess_executor_
private

Definition at line 165 of file cp_gcalcli_connection.hpp.

Referenced by checkConnection(), executeGcalcli(), onInitialize(), and update().


The documentation for this class was generated from the following files: