Skip to content

Shutdown callback for service interfaces#31

Merged
ClemensElflein merged 1 commit into
xtech:mainfrom
rovo89:feat/shutdown-callback
Jun 16, 2026
Merged

Shutdown callback for service interfaces#31
ClemensElflein merged 1 commit into
xtech:mainfrom
rovo89:feat/shutdown-callback

Conversation

@rovo89

@rovo89 rovo89 commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added shutdown callback support to the service interface. Applications can register a callback to run when termination signals (SIGINT/SIGTERM) are received; the callback is invoked after the service stops. The callback must be registered before starting the service when signal handling is enabled.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8971a911-41ed-4e13-a373-d221e92009b8

📥 Commits

Reviewing files that changed from the base of the PR and between a1e4529 and 85ed2b4.

📒 Files selected for processing (2)
  • libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp
  • libxbot-service-interface/src/XbotServiceInterface.cpp

📝 Walkthrough

Walkthrough

The PR adds a ShutdownCallback type alias (std::function<void()>) and SetShutdownCallback() to the XbotServiceInterface public API. The implementation stores the callback globally, invokes it in SignalHandler after Stop() on SIGINT/SIGTERM, and fixes the sigaction struct to be locally scoped with explicit sigemptyset initialization.

Changes

Shutdown Callback Feature

Layer / File(s) Summary
Public API: ShutdownCallback type and declaration
libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp
Adds <functional> include, ShutdownCallback type alias, and SetShutdownCallback() declaration with documentation on invocation order and registration requirement.
Implementation: callback storage, SignalHandler, and sigaction fix
libxbot-service-interface/src/XbotServiceInterface.cpp
Introduces global shutdown_callback, implements SetShutdownCallback() via move-assignment, updates SignalHandler to call Stop() then invoke the callback if set, and replaces the shared sigaction struct with a local zero-initialized instance using sigemptyset.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 A signal arrives, the service must end,
Now a callback can join, around every bend!
Stop() fires first, then your function is called,
Set it before Start() — or be quite appalled.
The sigaction mask is cleared clean and bright,
This rabbit hops onward — shutdown done right! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a shutdown callback feature to service interfaces, which is exactly what the changeset implements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rovo89

rovo89 commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator Author

@ClemensElflein Is it fine to use std::function for service interfaces? We don't seem to have portables there.
Also, didn't I have push permissions back then?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp (1)

20-35: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the Start() Doxygen block adjacent to Start().

The new ShutdownCallback alias now sits between the Start() documentation and the Start() declaration, so generated docs will attach the Start() text to the alias instead.

📚 Proposed documentation layout
-/**
- * Call this method to start xbot_framework.
- *
- * `@param` register_signal_handlers true to handle signals (CTRL+C), false to
- * manually stop using Stop()
- * `@return` The context
- */
 using ShutdownCallback = std::function<void()>;
 
 /**
  * Register a callback invoked after Stop() when SIGINT/SIGTERM is received.
  * Must be called before Start() if register_signal_handlers is true.
  */
 void SetShutdownCallback(ShutdownCallback callback);
 
+/**
+ * Call this method to start xbot_framework.
+ *
+ * `@param` register_signal_handlers true to handle signals (CTRL+C), false to
+ * manually stop using Stop()
+ * `@return` The context
+ */
 Context Start(bool register_signal_handlers = true, std::string bind_ip = "0.0.0.0", bool start_rest_api = false);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp`
around lines 20 - 35, The Doxygen documentation block for the Start() method is
not adjacent to its declaration due to the ShutdownCallback type alias and
SetShutdownCallback() method being placed between them. This causes the
documentation to attach to the wrong entity. Move the ShutdownCallback type
alias definition and the SetShutdownCallback() method declaration to appear
before the Start() Doxygen comment block, so that the documentation comment for
Start() is directly adjacent to the Start() method declaration.
🧹 Nitpick comments (1)
libxbot-service-interface/src/XbotServiceInterface.cpp (1)

38-39: ⚡ Quick win

Include <utility> for std::move.

Line 39 uses std::move, but this file does not include <utility> directly; relying on transitive includes is fragile across toolchains.

🧩 Proposed include fix
 `#include` <csignal>
 `#include` <mutex>
+#include <utility>
 `#include` <xbot-service-interface/XbotServiceInterface.hpp>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libxbot-service-interface/src/XbotServiceInterface.cpp` around lines 38 - 39,
The SetShutdownCallback function uses std::move to move the callback parameter,
but the file does not directly include the <utility> header where std::move is
defined. Add `#include` <utility> to the includes section at the top of
XbotServiceInterface.cpp to ensure std::move is properly declared, avoiding
reliance on fragile transitive includes that may break across different
toolchains.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libxbot-service-interface/src/XbotServiceInterface.cpp`:
- Around line 31-39: The SignalHandler function violates async-signal-safety by
directly calling Stop() (which uses logging, mutexes, and virtual calls) and
invoking shutdown_callback (arbitrary C++ code). Additionally, shutdown_callback
is accessed without synchronization between the read in SignalHandler and
mutation in SetShutdownCallback, creating a data race. Refactor to defer signal
handling: use sigwait() on a dedicated thread or implement a self-pipe/eventfd
mechanism to handle the actual Stop() call and callback invocation from a normal
(non-signal) execution context with proper synchronization. Also add `#include`
<utility> at the top of the file since std::move is used in SetShutdownCallback
without it.

---

Outside diff comments:
In
`@libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp`:
- Around line 20-35: The Doxygen documentation block for the Start() method is
not adjacent to its declaration due to the ShutdownCallback type alias and
SetShutdownCallback() method being placed between them. This causes the
documentation to attach to the wrong entity. Move the ShutdownCallback type
alias definition and the SetShutdownCallback() method declaration to appear
before the Start() Doxygen comment block, so that the documentation comment for
Start() is directly adjacent to the Start() method declaration.

---

Nitpick comments:
In `@libxbot-service-interface/src/XbotServiceInterface.cpp`:
- Around line 38-39: The SetShutdownCallback function uses std::move to move the
callback parameter, but the file does not directly include the <utility> header
where std::move is defined. Add `#include` <utility> to the includes section at
the top of XbotServiceInterface.cpp to ensure std::move is properly declared,
avoiding reliance on fragile transitive includes that may break across different
toolchains.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 172955a2-f1fc-4cad-96e2-fa3c19e86484

📥 Commits

Reviewing files that changed from the base of the PR and between 9b52058 and a1e4529.

📒 Files selected for processing (2)
  • libxbot-service-interface/include/xbot-service-interface/XbotServiceInterface.hpp
  • libxbot-service-interface/src/XbotServiceInterface.cpp

Comment thread libxbot-service-interface/src/XbotServiceInterface.cpp
@rovo89

rovo89 commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator Author

Needed for ClemensElflein/open_mower_ros#304.

@rovo89 rovo89 force-pushed the feat/shutdown-callback branch from a1e4529 to 54a0154 Compare June 16, 2026 21:05
@ClemensElflein

Copy link
Copy Markdown
Member

@ClemensElflein Is it fine to use std::function for service interfaces? We don't seem to have portables there. Also, didn't I have push permissions back then?

Yes, the interface side is linux only, so we can go fancy 👍

@ClemensElflein

Copy link
Copy Markdown
Member

LGTM, thank you for the PR!

@ClemensElflein ClemensElflein force-pushed the feat/shutdown-callback branch from 54a0154 to 85ed2b4 Compare June 16, 2026 21:22
@ClemensElflein ClemensElflein merged commit e112a9f into xtech:main Jun 16, 2026
5 of 6 checks passed
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.

2 participants