Skip to content
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

fix: C++ Auto-Reconnect #237

Merged
merged 6 commits into from
Dec 16, 2024
Merged
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
5 changes: 3 additions & 2 deletions languages/c-structs/templates/sdk/src/Logger/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ namespace FireboltSDK {
const string time = WPEFramework::Core::Time::Now().ToTimeOnly(true);
const string categoryName = WPEFramework::Core::EnumerateType<Logger::Category>(category).Data();
if (categoryName.empty() != true) {
sprintf(formattedMsg, "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
} else {
sprintf(formattedMsg, "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
}

LOG_MESSAGE(formattedMsg);
}
}
Expand Down
4 changes: 2 additions & 2 deletions languages/c/src/shared/src/Logger/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ namespace FireboltSDK {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
if (categoryName.empty() != true) {
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
} else {
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
}
#pragma GCC diagnostic pop
LOG_MESSAGE(formattedMsg);
Expand Down
40 changes: 37 additions & 3 deletions languages/cpp/src/shared/src/Accessor/Accessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "Accessor.h"

#include <chrono>

namespace FireboltSDK {

Accessor* Accessor::_singleton = nullptr;
Expand Down Expand Up @@ -65,13 +67,16 @@ namespace FireboltSDK {
return Event::Instance();
}

Firebolt::Error Accessor::CreateTransport(const string& url, const Transport<WPEFramework::Core::JSON::IElement>::Listener& listener, const uint32_t waitTime = DefaultWaitTime)
Firebolt::Error Accessor::CreateTransport(const string& url, const uint32_t waitTime = DefaultWaitTime)
{
if (_transport != nullptr) {
delete _transport;
}

_transport = new Transport<WPEFramework::Core::JSON::IElement>(static_cast<WPEFramework::Core::URL>(url), waitTime, listener);
_transport = new Transport<WPEFramework::Core::JSON::IElement>(
static_cast<WPEFramework::Core::URL>(url),
waitTime,
std::bind(&Accessor::ConnectionChanged, this, std::placeholders::_1, std::placeholders::_2));

ASSERT(_transport != nullptr);
return ((_transport != nullptr) ? Firebolt::Error::None : Firebolt::Error::Timedout);
Expand All @@ -86,9 +91,38 @@ namespace FireboltSDK {
return Firebolt::Error::None;
}

void Accessor::ConnectionChanged(const bool connected, const Firebolt::Error error)
{
_connectionChangeSync.signal(); // Signal waiting thread that the connection changed
_connected = connected;
if (_connectionChangeListener != nullptr) { // Notify a listener about the connection change
_connectionChangeListener(connected, error);
}
}

Transport<WPEFramework::Core::JSON::IElement>* Accessor::GetTransport()
{
ASSERT(_transport != nullptr);
if (_transport == nullptr || ! _connected) { // Try to connect if not connected: application has not yet connected or connection has been lost
DestroyTransport(); // Clean the transport if necessary

_connectionChangeSync.reset();
Firebolt::Error status = CreateTransport( // Recreate the transport with the configuration passed to CTor
_config.WsUrl.Value().c_str(),
_config.WaitTime.Value());

bool ret = _connectionChangeSync.wait_for(_config.WaitTime.Value()); // Wait for the signal that the connection has changed, but no more than `WaitTime`

if (ret) { // Check if the connection successfully established
ASSERT(_transport != nullptr);
if (status == Firebolt::Error::None) { // If yes, proceed with the configuration of Async and Event-Handler
Async::Instance().Configure(_transport);
status = CreateEventHandler();
}
} else { // If the connection cannot be established, clean the transport
DestroyTransport();
}
}

return _transport;
}

Expand Down
51 changes: 49 additions & 2 deletions languages/cpp/src/shared/src/Accessor/Accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "Event/Event.h"
#include "Logger/Logger.h"

#include <condition_variable>
#include <mutex>

namespace FireboltSDK {
class Accessor {
private:
Expand Down Expand Up @@ -107,16 +110,30 @@ namespace FireboltSDK {

Firebolt::Error Connect(const Transport<WPEFramework::Core::JSON::IElement>::Listener& listener)
{
Firebolt::Error status = CreateTransport(_config.WsUrl.Value().c_str(), listener, _config.WaitTime.Value());
RegisterConnectionChangeListener(listener);
Firebolt::Error status = CreateTransport(_config.WsUrl.Value().c_str(), _config.WaitTime.Value());
if (status == Firebolt::Error::None) {
Async::Instance().Configure(_transport);
status = CreateEventHandler();
}
return status;
}

void RegisterConnectionChangeListener(const Transport<WPEFramework::Core::JSON::IElement>::Listener& listener)
{
_connectionChangeListener = listener;
}

void UnregisterConnnectionChangeListener()
{
_connectionChangeListener = nullptr;
}

Firebolt::Error Disconnect()
{
if (_transport == nullptr) {
return Firebolt::Error::None;
}
Firebolt::Error status = Firebolt::Error::None;
status = DestroyTransport();
if (status == Firebolt::Error::None) {
Expand All @@ -126,19 +143,49 @@ namespace FireboltSDK {
return status;
}

bool IsConnected() const
{
return _connected;
}

Event& GetEventManager();
Transport<WPEFramework::Core::JSON::IElement>* GetTransport();

private:
Firebolt::Error CreateEventHandler();
Firebolt::Error DestroyEventHandler();
Firebolt::Error CreateTransport(const string& url, const Transport<WPEFramework::Core::JSON::IElement>::Listener& listener, const uint32_t waitTime);
Firebolt::Error CreateTransport(const string& url, const uint32_t waitTime);
Firebolt::Error DestroyTransport();

void ConnectionChanged(const bool connected, const Firebolt::Error error);

private:
WPEFramework::Core::ProxyType<WorkerPoolImplementation> _workerPool;
Transport<WPEFramework::Core::JSON::IElement>* _transport;
static Accessor* _singleton;
Config _config;
struct {
std::mutex m;
std::condition_variable cv;
bool ready = false;
void reset() {
std::lock_guard lk(m);
ready = false;
}
bool wait_for(unsigned duration_ms) {
std::unique_lock lk(m);
bool ret = cv.wait_for(lk, std::chrono::milliseconds(duration_ms), [&]{ return ready; });
lk.unlock();
return ret;
}
void signal() {
std::lock_guard lk(m);
ready = true;
cv.notify_one();
}
} _connectionChangeSync; // Synchronize a thread that is waiting for a connection if that one that is notified about connection changes

bool _connected = false;
Transport<WPEFramework::Core::JSON::IElement>::Listener _connectionChangeListener = nullptr;
};
}
4 changes: 2 additions & 2 deletions languages/cpp/src/shared/src/Logger/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ namespace FireboltSDK {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
if (categoryName.empty() != true) {
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), categoryName.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
} else {
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
snprintf(formattedMsg, sizeof(formattedMsg), "--->\033[1;32m[%s]:[%s][%s:%d](%s)<PID:%d><TID:%ld> : %s\033[0m\n", time.c_str(), module.c_str(), WPEFramework::Core::File::FileName(file).c_str(), line, function.c_str(), TRACE_PROCESS_ID, TRACE_THREAD_ID, msg);
}
#pragma GCC diagnostic pop
LOG_MESSAGE(formattedMsg);
Expand Down
23 changes: 23 additions & 0 deletions languages/cpp/templates/sdk/include/firebolt.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,29 @@ struct IFireboltAccessor {
*/
virtual Firebolt::Error Connect ( OnConnectionChanged listener ) = 0;

/**
* @brief Register a callback for any changes in the connection to the endpoint. Only a single callback is supported.
*
* @param listener Connection status listener
*
* @return None
*/
virtual void RegisterConnectionChangeListener ( OnConnectionChanged listener ) = 0;

/**
* @brief Unregister previously registered callback.
*
* @return None
*/
virtual void UnregisterConnnectionChangeListener ( ) = 0;

/**
* @brief Returs whether there is a connection to the endpoint
*
* @return bool
*/
virtual bool IsConnected ( ) const = 0;

/**
* @brief Disconnects from the Websocket endpoint.
*
Expand Down
6 changes: 3 additions & 3 deletions languages/cpp/templates/sdk/scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ then
fi

rm -rf ${SdkPath}/build/src/libFireboltSDK.so
cmake -B${SdkPath}/build -S${SdkPath} -DSYSROOT_PATH=${SysrootPath} -DENABLE_TESTS=${EnableTest} -DHIDE_NON_EXTERNAL_SYMBOLS=OFF -DFIREBOLT_ENABLE_STATIC_LIB=${EnableStaticLib}
cmake --build ${SdkPath}/build
cmake -B${SdkPath}/build -S${SdkPath} -DSYSROOT_PATH=${SysrootPath} -DENABLE_TESTS=${EnableTest} -DHIDE_NON_EXTERNAL_SYMBOLS=OFF -DFIREBOLT_ENABLE_STATIC_LIB=${EnableStaticLib} || exit 1
cmake --build ${SdkPath}/build || exit 1
if [ -f "${SdkPath}/build/src/libFireboltSDK.so" ];
then
cmake --install ${SdkPath}/build --prefix ${SdkPath}/build/Firebolt/usr
cmake --install ${SdkPath}/build --prefix ${SdkPath}/build/Firebolt/usr || exit 1
fi
24 changes: 21 additions & 3 deletions languages/cpp/templates/sdk/src/firebolt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ namespace Firebolt {

static FireboltAccessorImpl& Instance()
{
static FireboltAccessorImpl* instance = new FireboltAccessorImpl();
ASSERT(instance != nullptr);
return *instance;
if (_singleton == nullptr) {
_singleton = new FireboltAccessorImpl();
ASSERT(_singleton != nullptr);
}
return *_singleton;
}

static void Dispose()
Expand All @@ -67,6 +69,7 @@ namespace Firebolt {
ASSERT(_singleton != nullptr);
if (_singleton != nullptr) {
delete _singleton;
singleton = nullptr;
}
}

Expand All @@ -86,6 +89,21 @@ namespace Firebolt {
return _accessor->Connect(listener);
}

void RegisterConnectionChangeListener( OnConnectionChanged listener ) override
{
return _accessor->RegisterConnectionChangeListener(listener);
}

void UnregisterConnnectionChangeListener() override
{
_accessor->UnregisterConnnectionChangeListener();
}

bool IsConnected() const override
{
return _accessor->IsConnected();
}

Firebolt::Error Disconnect() override
{
return _accessor->Disconnect();
Expand Down
Loading