-
Notifications
You must be signed in to change notification settings - Fork 36
feat: add heartbeat feature to auto-terminate program on failure #425
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
base: development
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,6 @@ | ||||||||
| #include <thread> | ||||||||
| #include <chrono> | ||||||||
| #include <iostream> | ||||||||
| #include "OdbDesignServerApp.h" | ||||||||
| #include "Controllers/HelloWorldController.h" | ||||||||
| #include "Controllers/FileUploadController.h" | ||||||||
|
|
@@ -11,9 +14,15 @@ using namespace Odb::Lib::App; | |||||||
|
|
||||||||
| namespace Odb::App::Server | ||||||||
| { | ||||||||
| OdbDesignServerApp* OdbDesignServerApp::inst_ = nullptr; | ||||||||
| int heartbeatInterval; | ||||||||
| OdbDesignServerApp::OdbDesignServerApp(int argc, char* argv[]) | ||||||||
| : OdbServerAppBase(argc, argv) | ||||||||
| { | ||||||||
| { | ||||||||
| inst_ = this; | ||||||||
| heartbeatInterval = args().heartbeatInterval(); | ||||||||
| // set last heartbeat time to now | ||||||||
| lastHeartbeat_.store(std::chrono::steady_clock::now(), std::memory_order_relaxed); | ||||||||
| } | ||||||||
|
|
||||||||
| //OdbDesignServerApp::~OdbDesignServerApp() | ||||||||
|
|
@@ -44,6 +53,24 @@ namespace Odb::App::Server | |||||||
| m_vecControllers.push_back(std::make_shared<DesignsController>(*this)); | ||||||||
| } | ||||||||
|
|
||||||||
| void monitorHeartbeat() | ||||||||
| { | ||||||||
| auto lastTime = OdbDesignServerApp::inst_->lastHeartbeat_.load(std::memory_order_relaxed); | ||||||||
| while (true) | ||||||||
| { | ||||||||
| std::this_thread::sleep_for(std::chrono::seconds(1)); | ||||||||
| auto now = std::chrono::steady_clock::now(); | ||||||||
| auto diff = now - lastTime; | ||||||||
| // check heartbeat | ||||||||
| if (diff > std::chrono::seconds(heartbeatInterval)) | ||||||||
| { | ||||||||
| std::cerr << "Heartbeat timeout, exiting..." << std::endl; | ||||||||
| exit(0); | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling Style Guide References
Suggested change
Footnotes |
||||||||
| } | ||||||||
| lastTime = OdbDesignServerApp::inst_->lastHeartbeat_.load(std::memory_order_relaxed); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| bool OdbDesignServerApp::preServerRun() | ||||||||
| { | ||||||||
| // CORS | ||||||||
|
|
@@ -70,6 +97,10 @@ namespace Odb::App::Server | |||||||
| auto basicRequestAuth = std::make_unique<BasicRequestAuthentication>(BasicRequestAuthentication(disableAuth)); | ||||||||
| request_auth(std::move(basicRequestAuth)); | ||||||||
|
|
||||||||
| // start heart beat monitor | ||||||||
| std::thread heartbeatMonitor(monitorHeartbeat); | ||||||||
| heartbeatMonitor.detach(); // run in background | ||||||||
|
|
||||||||
| return true; | ||||||||
| } | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,15 @@ namespace Odb::App::Server | |
|
|
||
| //Utils::ExitCode Run() override; | ||
|
|
||
| protected: | ||
| static OdbDesignServerApp* inst_; | ||
| // store last heartbeat time | ||
| std::atomic<std::chrono::steady_clock::time_point> lastHeartbeat_; | ||
|
Comment on lines
+17
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These members ( Style Guide ReferencesFootnotes |
||
| void updateLastHeartbeat() | ||
| { | ||
| lastHeartbeat_.store(std::chrono::steady_clock::now(), std::memory_order_relaxed); | ||
| } | ||
|
|
||
| protected: | ||
| void add_controllers() override; | ||
|
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line uses the global singleton
inst_to access the application object. This creates a tight coupling and dependency on a global variable1. TheRouteControllerbase class already provides access to the server application via them_serverAppmember. You can usedynamic_castto safely cast it to your specific application class and call the method. This approach uses dependency injection and avoids global state, which is a much cleaner design.Style Guide References
Footnotes
Avoid global singletons. (link) ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Gemini states, you already have access to
m_serverApp. You can use that and get rid of the singleton object.