Skip to content

Conversation

@alvintps
Copy link

@alvintps alvintps commented Jan 16, 2026

This PR addresses Issue #1057. active_server is no longer set to true in the server loop. Instead it is true on construction, and set to false on destruction.

Summary by CodeRabbit

  • Bug Fixes

    • Publisher now defaults to an active server state and no longer uses a redundant reassignment, preventing unintended loop behavior.
    • Prevents potential hangs when a runtime error is thrown during behavior-tree execution.
  • Tests

    • Added tests that verify runtime-error handling in behavior-tree execution, including asynchronous checks to detect and prevent hangs.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

Groot2Publisher now default-initializes its internal active_server flag to true and removed the redundant assignment in the server loop. A new unit test verifies that a BT::RuntimeError thrown during a tree tick does not cause the publisher to hang.

Changes

Cohort / File(s) Summary
Groot2Publisher state change
src/loggers/groot2_publisher.cpp
Default-initialize _p->active_server to true; removed explicit _p->active_server = true from serverLoop() so the loop uses the member's initial value.
Tests — new exception regression test
tests/gtest_groot2_publisher.cpp, tests/CMakeLists.txt
Add gtest_groot2_publisher.cpp which defines ThrowRuntimeError, builds a tree that throws BT::RuntimeError, asserts tickOnce() throws and does not hang (async wait up to 1s). Test added to tests/CMakeLists.txt.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I flipped a flag to true at start,
So loops won't lose their beating heart.
When errors spring and tumble through,
The publisher hops and carries you,
Safe tick, safe tick — a joyful art! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change—fixing an infinite loop in Groot2Publisher's destructor—which aligns with the changeset's core fix.
Description check ✅ Passed The description covers the core change (active_server initialization and destruction behavior) but lacks details on testing verification and lacks explicit reference to the unit test added.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@alvintps alvintps force-pushed the master branch 2 times, most recently from 0c1629a to 0456e24 Compare January 16, 2026 15:09
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/gtest_groot2_publisher.cpp`:
- Around line 34-39: The test EnsureNoInfiniteLoopOnThrow currently launches
throwRuntimeError with std::async which can block in the std::future destructor;
replace this with a subprocess-based approach: execute throwRuntimeError in a
child process (e.g., fork/exec or spawning a helper binary) from the test, have
the parent wait with a timeout, on timeout kill the child and fail the test, and
on child exit check its exit status to assert behavior. Locate the test by name
EnsureNoInfiniteLoopOnThrow and the target function throwRuntimeError and
implement the fork/waitpid + alarm/timeout (or spawn helper process) pattern so
the test runner cannot be blocked by a hanging async task.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b79f96 and 8e58767.

📒 Files selected for processing (2)
  • src/loggers/groot2_publisher.cpp
  • tests/gtest_groot2_publisher.cpp
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: C++ code must follow Google C++ style with 90-character line limit and 2-space indent
All C++ code must be processed by clang-format before submission
Run clang-tidy-21 checks on C++ code before submitting PRs

Files:

  • tests/gtest_groot2_publisher.cpp
  • src/loggers/groot2_publisher.cpp
tests/**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Test files must use Google Test framework and be located in the tests/ directory

Files:

  • tests/gtest_groot2_publisher.cpp
tests/gtest_*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

All test files must be runnable via CTest and should follow the naming convention of gtest_*.cpp for categorized test files

Files:

  • tests/gtest_groot2_publisher.cpp
src/**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

All behavior tree nodes must inherit from TreeNode base class defined in include/behaviortree_cpp/tree_node.h

Files:

  • src/loggers/groot2_publisher.cpp
🧠 Learnings (2)
📚 Learning: 2026-01-09T08:28:16.736Z
Learnt from: CR
Repo: BehaviorTree/BehaviorTree.CPP PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T08:28:16.736Z
Learning: Applies to tests/gtest_*.cpp : All test files must be runnable via CTest and should follow the naming convention of gtest_*.cpp for categorized test files

Applied to files:

  • tests/gtest_groot2_publisher.cpp
📚 Learning: 2026-01-09T08:28:16.736Z
Learnt from: CR
Repo: BehaviorTree/BehaviorTree.CPP PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T08:28:16.736Z
Learning: Applies to tests/**/*.{cpp,h,hpp} : Test files must use Google Test framework and be located in the tests/ directory

Applied to files:

  • tests/gtest_groot2_publisher.cpp
🧬 Code graph analysis (1)
tests/gtest_groot2_publisher.cpp (1)
include/behaviortree_cpp/exceptions.h (1)
  • RuntimeError (59-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (ubuntu-22.04, tsan)
  • GitHub Check: industrial_ci (humble, main)
  • GitHub Check: build (ubuntu-22.04, asan_ubsan)
  • GitHub Check: industrial_ci (rolling, main)
  • GitHub Check: build (windows-latest)
  • GitHub Check: industrial_ci (jazzy, main)
  • GitHub Check: pixi_conda_build (windows-latest)
  • GitHub Check: clang-tidy
  • GitHub Check: pixi_conda_build (ubuntu-latest)
🔇 Additional comments (2)
src/loggers/groot2_publisher.cpp (1)

84-84: Active server init aligns with shutdown flow.

Initializing BT::Groot2Publisher::PImpl::active_server to true and only clearing it in the destructor avoids the loop reactivating itself.

tests/gtest_groot2_publisher.cpp (1)

20-31: Helper covers the exception path well.

Nice, focused regression setup for the runtime-error tick and publisher teardown.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/gtest_groot2_publisher.cpp`:
- Around line 1-7: Add the missing header declaration for std::exit by including
<cstdlib> in the test translation unit; update the top of
tests/gtest_groot2_publisher.cpp so that std::exit is declared (used where
std::exit is called around the test teardown), ensuring compilation doesn't rely
on transitive includes.
🧹 Nitpick comments (1)
tests/gtest_groot2_publisher.cpp (1)

36-43: Consider a more generous timeout to reduce CI flakiness.

wait_for(1s) may be tight on busy/slow runners. A longer or configurable timeout would make the test more robust.

🔧 Suggested change
-  auto status = fut.wait_for(1s);
+  auto status = fut.wait_for(5s);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7a2cc8 and 45f7670.

📒 Files selected for processing (3)
  • src/loggers/groot2_publisher.cpp
  • tests/CMakeLists.txt
  • tests/gtest_groot2_publisher.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/loggers/groot2_publisher.cpp
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: C++ code must follow Google C++ style with 90-character line limit and 2-space indent
All C++ code must be processed by clang-format before submission
Run clang-tidy-21 checks on C++ code before submitting PRs

Files:

  • tests/gtest_groot2_publisher.cpp
tests/**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

Test files must use Google Test framework and be located in the tests/ directory

Files:

  • tests/gtest_groot2_publisher.cpp
tests/gtest_*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

All test files must be runnable via CTest and should follow the naming convention of gtest_*.cpp for categorized test files

Files:

  • tests/gtest_groot2_publisher.cpp
🧠 Learnings (2)
📚 Learning: 2026-01-09T08:28:16.736Z
Learnt from: CR
Repo: BehaviorTree/BehaviorTree.CPP PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T08:28:16.736Z
Learning: Applies to tests/gtest_*.cpp : All test files must be runnable via CTest and should follow the naming convention of gtest_*.cpp for categorized test files

Applied to files:

  • tests/gtest_groot2_publisher.cpp
  • tests/CMakeLists.txt
📚 Learning: 2026-01-09T08:28:16.736Z
Learnt from: CR
Repo: BehaviorTree/BehaviorTree.CPP PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T08:28:16.736Z
Learning: Applies to tests/**/*.{cpp,h,hpp} : Test files must use Google Test framework and be located in the tests/ directory

Applied to files:

  • tests/gtest_groot2_publisher.cpp
  • tests/CMakeLists.txt
🧬 Code graph analysis (1)
tests/gtest_groot2_publisher.cpp (1)
include/behaviortree_cpp/exceptions.h (1)
  • RuntimeError (59-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: pixi_conda_build (ubuntu-latest)
  • GitHub Check: pixi_conda_build (windows-latest)
  • GitHub Check: clang-tidy
  • GitHub Check: industrial_ci (rolling, main)
  • GitHub Check: industrial_ci (humble, main)
  • GitHub Check: industrial_ci (jazzy, main)
  • GitHub Check: build (ubuntu-22.04, asan_ubsan)
  • GitHub Check: build (ubuntu-22.04, tsan)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-22.04)
🔇 Additional comments (1)
tests/CMakeLists.txt (1)

14-16: LGTM — test is properly registered.

Adding the new test file to BT_TESTS is correct for discovery and build.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1 to +7
#include <chrono>
#include <future>

#include <behaviortree_cpp/loggers/groot2_protocol.h>
#include <behaviortree_cpp/loggers/groot2_publisher.h>
#include <gtest/gtest.h>

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add the missing <cstdlib> include for std::exit.

Line 42 uses std::exit, which should be declared in <cstdlib> rather than relying on transitive includes.

🔧 Suggested change
 `#include` <chrono>
 `#include` <future>
+ `#include` <cstdlib>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <chrono>
#include <future>
#include <behaviortree_cpp/loggers/groot2_protocol.h>
#include <behaviortree_cpp/loggers/groot2_publisher.h>
#include <gtest/gtest.h>
`#include` <chrono>
`#include` <future>
`#include` <cstdlib>
`#include` <behaviortree_cpp/loggers/groot2_protocol.h>
`#include` <behaviortree_cpp/loggers/groot2_publisher.h>
`#include` <gtest/gtest.h>
🤖 Prompt for AI Agents
In `@tests/gtest_groot2_publisher.cpp` around lines 1 - 7, Add the missing header
declaration for std::exit by including <cstdlib> in the test translation unit;
update the top of tests/gtest_groot2_publisher.cpp so that std::exit is declared
(used where std::exit is called around the test teardown), ensuring compilation
doesn't rely on transitive includes.

@facontidavide
Copy link
Collaborator

facontidavide commented Jan 16, 2026

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