Skip to content

Send only to opened queues - #1871

Draft
asahtik wants to merge 1 commit into
developfrom
bugfix/remove_add_topic
Draft

Send only to opened queues#1871
asahtik wants to merge 1 commit into
developfrom
bugfix/remove_add_topic

Conversation

@asahtik

@asahtik asahtik commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Purpose

This fixes topics not sending data when removing and re-adding them.

Specification

Removing a topic closes the created queue but does not unlink it from the output (this object is not available at that point). The output then tried to send to the closed queue (before sending to the new queue) which blocked the output.

Dependencies & Potential Impact

None / not applicable

Deployment Plan

None / not applicable

Testing & Validation

None / not applicable

Summary by CodeRabbit

  • Bug Fixes
    • Improved message delivery by skipping closed input queues during dispatch, preventing unnecessary send attempts and related errors.
    • Left event handling behavior unchanged.

Copilot AI review requested due to automatic review settings July 2, 2026 12:57
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change modifies Node::Output::send so that it checks whether each connected input's message queue is closed before attempting to send a message, skipping closed queues instead of unconditionally sending to all connected queues.

Changes

Closed Queue Check in Message Dispatch

Layer / File(s) Summary
Skip closed queues in send loop
src/pipeline/Node.cpp
Node::Output::send now checks isClosed() on each connected input queue before calling send(msg), avoiding sends to closed queues.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Poem

A tiny check, a hop, a skip,
No message sent on a closed-up chip,
This bunny checks before it sends,
Saving errors, making amends,
Thump-thump goes the safer code! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the core change: outputs now skip closed queues and send only to open ones.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/remove_add_topic

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates host-side Node::Output message dispatch to avoid sending to queues that have been closed (notably when a topic is removed and later re-added), preventing the output path from getting stuck on defunct queue connections.

Changes:

  • Guard Node::Output::send() so it only sends to non-closed connected queues.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pipeline/Node.cpp
Comment on lines 248 to 250
for(auto& messageQueue : connectedInputs) {
messageQueue->send(msg);
if(!messageQueue->isClosed()) messageQueue->send(msg);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Out of curiosity, where did you hit this? Seems like something that would be hit quite often so I am surprised we haven't hit it yet

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This PR fixes the issue Removal of RemoteConnection before pipeline is started doesn't work. In most cases if a queue closes it means that the pipeline is shutting down. I don't believe closing a queue during runtime is handled very well in some parts of Depthai.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@src/pipeline/Node.cpp`:
- Around line 247-251: `Node::Output::trySend()` still attempts
`MessageQueue::trySend()` on every connected input, which can throw if a queue
is already closed. Update the send loop in `Node::Output::trySend()` to mirror
the `sendToInputs` logic by checking `isClosed()` on each `messageQueue` before
calling `trySend()`, so closed inputs are skipped instead of causing
non-blocking sends to fail.
- Around line 247-251: The `sendToInputs` lambda in `Node::send()` still needs
the same closed-queue guard for `MessageQueue::trySend()` as it already has for
`send()`. Update the loop over `connectedInputs` so it checks
`messageQueue->isClosed()` before invoking either send path, and ensure any
`trySend()` call is skipped for closed queues to keep behavior consistent with
the guarded `send()` logic.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 397a52ab-8d4d-4ac7-a52e-a5d25a9b2b0f

📥 Commits

Reviewing files that changed from the base of the PR and between 1b70a3d and 71abbf1.

📒 Files selected for processing (1)
  • src/pipeline/Node.cpp
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: copilot-pull-request-reviewer
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-03-24T22:39:04.364Z
Learnt from: MaticTonin
Repo: luxonis/depthai-core PR: 1732
File: src/pipeline/Pipeline.cpp:705-705
Timestamp: 2026-03-24T22:39:04.364Z
Learning: Do not flag the `!= ""` part of the auto-calibration condition as redundant when it appears in `PipelineImpl::build()` (or closely related pipeline build logic). If the code uses `utility::getEnvAs<std::string>(..., default)` with a default such as `"ON_START"`, the explicit empty-string guard may still be intentional to treat an explicitly empty env var as “OFF/disabled” (or to avoid special-casing elsewhere). Only consider removing `!= ""` if the codebase has an explicit, enforceable guarantee that `DEPTHAI_AUTOCALIBRATION` can never be set to an empty string (e.g., via validated parsing/CI checks); otherwise, keep the guard.

Applied to files:

  • src/pipeline/Node.cpp

Comment thread src/pipeline/Node.cpp
Comment on lines 247 to 251
auto sendToInputs = [this, &msg]() {
for(auto& messageQueue : connectedInputs) {
messageQueue->send(msg);
if(!messageQueue->isClosed()) messageQueue->send(msg);
}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

depthai-core MessageQueue trySend behavior on closed queue

💡 Result:

In the depthai-core library, the trySend method of the MessageQueue class attempts to place a message into the queue [1][2]. When a queue has been closed (or destroyed), attempting to interact with it—such as through has, tryGet, or similar accessors—typically triggers a QueueException with the message CLOSED_QUEUE_MESSAGE [3][4]. While explicit public documentation on the specific return value of trySend on a closed queue is limited, the internal implementation pattern for queue operations in depthai-core consistently checks for the closed/destroyed state [3][4]. If a queue is in a closed state, callers should anticipate that the operation will either throw a QueueException or return a status indicating failure, depending on the specific version and internal checks [3][4]. It is best practice to verify the state of the queue using isClosed before attempting to send messages to avoid exceptions or unexpected behavior in the pipeline [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the relevant source and implementation details.
git ls-files | rg '(^|/)Node\.cpp$|(^|/)MessageQueue(\.h|\.hpp|\.cpp)$|(^|/)MessageQueue'
echo '--- Node.cpp around trySend/send ---'
sed -n '220,310p' src/pipeline/Node.cpp

echo '--- MessageQueue declarations/definitions ---'
for f in $(git ls-files | rg 'MessageQueue(\.h|\.hpp|\.cpp)$'); do
  echo "### $f"
  sed -n '1,260p' "$f" | rg -n 'trySend|send|isClosed|closed|CLOSED_QUEUE_MESSAGE|QueueException|destroy'
done

Repository: luxonis/depthai-core

Length of output: 6048


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the API docs are available in the repo, inspect the exact contract for trySend.
git ls-files | rg 'docs|MessageQueue'

Repository: luxonis/depthai-core

Length of output: 535


🌐 Web query:

depthai MessageQueue trySend closed queue QueueException CLOSED_QUEUE_MESSAGE source

💡 Result:

In the DepthAI (dai) library, the error dai.MessageQueue.QueueException: MessageQueue was closed occurs when you attempt to interact with a queue (such as calling trySend, get, or tryGet) after the queue has been closed [1][2][3]. The string "MessageQueue was closed" corresponds to the static constant CLOSED_QUEUE_MESSAGE used within the MessageQueue class to signal this state [1][2]. Key causes for this exception include: - Pipeline Termination: The pipeline has stopped running, rendering its associated queues invalid [3][4]. - Device/Connection Issues: A hardware disconnect, PoE/IP connection loss, or device failure has occurred, leading to the closure of communication channels [3][4]. - Upstream Node Failure: A node providing data to the queue may have crashed or stopped, causing the output queue to close [3]. When this error is encountered, it generally indicates that the queue is no longer functional and should not be used further. To debug or resolve this, consider checking the following: - Verify that the pipeline is still running (e.g., check pipeline.isRunning) [3]. - Check device connectivity and power stability [3]. - Examine logs or perform testing to determine if specific nodes are failing under load [3]. - Ensure that your code is designed to handle this exception gracefully in scenarios where pipeline restarts or device reconnects might happen [3][5].

Citations:


Guard trySend() against closed queues too Node::Output::trySend() still calls MessageQueue::trySend() for every connected input, and that API throws when the queue is closed. Add the same isClosed() check here so non-blocking sends don’t fail as soon as one input closes.

🤖 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 `@src/pipeline/Node.cpp` around lines 247 - 251, `Node::Output::trySend()`
still attempts `MessageQueue::trySend()` on every connected input, which can
throw if a queue is already closed. Update the send loop in
`Node::Output::trySend()` to mirror the `sendToInputs` logic by checking
`isClosed()` on each `messageQueue` before calling `trySend()`, so closed inputs
are skipped instead of causing non-blocking sends to fail.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard trySend() the same way as send()
MessageQueue::trySend() still follows the closed-queue path here, so this loop should skip closed inputs before calling it to avoid inconsistent behavior with the guarded send() path.

🤖 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 `@src/pipeline/Node.cpp` around lines 247 - 251, The `sendToInputs` lambda in
`Node::send()` still needs the same closed-queue guard for
`MessageQueue::trySend()` as it already has for `send()`. Update the loop over
`connectedInputs` so it checks `messageQueue->isClosed()` before invoking either
send path, and ensure any `trySend()` call is skipped for closed queues to keep
behavior consistent with the guarded `send()` logic.

@asahtik asahtik added the testable_all run all tests label Jul 6, 2026
@asahtik
asahtik marked this pull request as draft July 8, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testable_all run all tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants