Skip to content

p2p robustness and scalability - #1222

Draft
gmartin82 wants to merge 3 commits into
eclipse-zenoh:mainfrom
gmartin82:ZEN-937
Draft

p2p robustness and scalability#1222
gmartin82 wants to merge 3 commits into
eclipse-zenoh:mainfrom
gmartin82:ZEN-937

Conversation

@gmartin82

@gmartin82 gmartin82 commented May 14, 2026

Copy link
Copy Markdown
Contributor

Description

Work in progress toward consistently starting interconnected peer zenoh-pico nodes at larger scales.

What does this PR do?

  • Make the listen connection limit configurable via CMake
  • Add connect timeout support to the C11 z_pub / z_sub examples
  • Update the peer mesh run script to use configurable connect timeout
  • Speed up run script log scanning and report time to full observed connectivity

Why is this change needed?

The peer-to-peer stress script needs to exercise larger interconnected zenoh-pico meshes, ideally up to 50 nodes, without relying on hardcoded connection limits or slow log parsing. This PR starts improving that workflow by making the listen limit configurable, allowing examples to keep retrying peer connects, and making the script report the actual time until full observed connectivity.

Related Issues


🏷️ Label-Based Checklist

Based on the labels applied to this PR, please complete these additional requirements:

Labels: internal

🏠 Internal Change

This PR is marked as internal (not user-facing):

  • No API changes - Public APIs unchanged
  • No behavior changes - External behavior identical
  • Refactoring/maintenance - Code improvements only
  • Tests still pass - All existing tests pass without modification

Lighter review: Internal changes may have lighter review requirements.

Instructions:

  1. Check off items as you complete them (change - [ ] to - [x])
  2. The PR checklist CI will verify these are completed

This checklist updates automatically when labels change, but preserves your checked boxes.

Work in progress toward consistently starting interconnected peer
zenoh-pico nodes at larger scales.

- Make the listen connection limit configurable via CMake
- Add connect timeout support to the C11 z_pub/z_sub examples
- Update the peer mesh run script to use configurable connect timeout
- Speed up run script log scanning and report time to full observed connectivity
@gmartin82 gmartin82 added the internal Changes not included in the changelog label May 14, 2026
Comment thread run.sh
@@ -0,0 +1,79 @@
nb=${1:-5}
Comment thread run.sh
connect_timeout=${3:--1}

echo "" > log
for i in $(seq -f "%03g" 1 1 $nb 2>/dev/null)
Comment thread run.sh
do
connect="$connect -e tcp/127.0.0.1:8$j -e tcp/127.0.0.1:9$j"
done
stdbuf -o0 ./build/examples/z_pub -m peer -l tcp/127.0.0.1:8$i -t $connect_timeout $connect -k demo/example/$i | while read line; do echo "[pub $i][$(date +%s.%N)] $line"; done >> log &
Comment thread run.sh
do
connect="$connect -e tcp/127.0.0.1:8$j -e tcp/127.0.0.1:9$j"
done
stdbuf -o0 ./build/examples/z_pub -m peer -l tcp/127.0.0.1:8$i -t $connect_timeout $connect -k demo/example/$i | while read line; do echo "[pub $i][$(date +%s.%N)] $line"; done >> log &
Comment thread run.sh
connect="$connect -e tcp/127.0.0.1:8$j -e tcp/127.0.0.1:9$j"
done
stdbuf -o0 ./build/examples/z_pub -m peer -l tcp/127.0.0.1:8$i -t $connect_timeout $connect -k demo/example/$i | while read line; do echo "[pub $i][$(date +%s.%N)] $line"; done >> log &
stdbuf -o0 ./build/examples/z_sub -m peer -l tcp/127.0.0.1:9$i -t $connect_timeout -e tcp/127.0.0.1:8$i $connect | while read line; do echo "[sub $i][$(date +%s.%N)] $line"; done >> log &
Comment thread run.sh
connect="$connect -e tcp/127.0.0.1:8$j -e tcp/127.0.0.1:9$j"
done
stdbuf -o0 ./build/examples/z_pub -m peer -l tcp/127.0.0.1:8$i -t $connect_timeout $connect -k demo/example/$i | while read line; do echo "[pub $i][$(date +%s.%N)] $line"; done >> log &
stdbuf -o0 ./build/examples/z_sub -m peer -l tcp/127.0.0.1:9$i -t $connect_timeout -e tcp/127.0.0.1:8$i $connect | while read line; do echo "[sub $i][$(date +%s.%N)] $line"; done >> log &
Comment thread run.sh
stdbuf -o0 ./build/examples/z_sub -m peer -l tcp/127.0.0.1:9$i -t $connect_timeout -e tcp/127.0.0.1:8$i $connect | while read line; do echo "[sub $i][$(date +%s.%N)] $line"; done >> log &
done

sleep $duration
Comment thread run.sh

if [[ $stop != "" ]]
then
echo OK $(($stop - $start)) seconds
Comment thread run.sh
then
echo OK $(($stop - $start)) seconds
else
echo KO $failure
Comment thread examples/unix/c11/z_pub.c
bool *add_matching_listener) {
int opt;
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:a")) != -1) {
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:at:")) != -1) {
Comment thread examples/unix/c11/z_sub.c
static int parse_args(int argc, char **argv, z_owned_config_t *config, char **ke, int *n) {
int opt;
while ((opt = getopt(argc, argv, "k:e:m:l:n:")) != -1) {
while ((opt = getopt(argc, argv, "k:e:m:l:n:t:")) != -1) {
Comment thread examples/unix/c11/z_pub.c
bool *add_matching_listener) {
int opt;
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:a")) != -1) {
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:at:")) != -1) {
Comment thread examples/unix/c11/z_pub.c
bool *add_matching_listener) {
int opt;
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:a")) != -1) {
while ((opt = getopt(argc, argv, "k:v:e:m:l:n:at:")) != -1) {
Comment thread examples/unix/c11/z_pub.c
break;
case 't':
#if defined(Z_FEATURE_UNSTABLE_API)
zp_config_insert(z_loan_mut(*config), Z_CONFIG_CONNECT_TIMEOUT_KEY, optarg);
Comment thread examples/unix/c11/z_pub.c
case '?':
if (optopt == 'k' || optopt == 'v' || optopt == 'e' || optopt == 'm' || optopt == 'l' ||
optopt == 'n') {
optopt == 'n' || optopt == 't') {
Comment thread examples/unix/c11/z_sub.c
static int parse_args(int argc, char **argv, z_owned_config_t *config, char **ke, int *n) {
int opt;
while ((opt = getopt(argc, argv, "k:e:m:l:n:")) != -1) {
while ((opt = getopt(argc, argv, "k:e:m:l:n:t:")) != -1) {
Comment thread examples/unix/c11/z_sub.c
static int parse_args(int argc, char **argv, z_owned_config_t *config, char **ke, int *n) {
int opt;
while ((opt = getopt(argc, argv, "k:e:m:l:n:")) != -1) {
while ((opt = getopt(argc, argv, "k:e:m:l:n:t:")) != -1) {
Comment thread examples/unix/c11/z_sub.c
break;
case 't':
#if defined(Z_FEATURE_UNSTABLE_API)
zp_config_insert(z_loan_mut(*config), Z_CONFIG_CONNECT_TIMEOUT_KEY, optarg);
Comment thread examples/unix/c11/z_sub.c
break;
case '?':
if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'l' || optopt == 'n') {
if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'l' || optopt == 'n' ||
Comment thread examples/unix/c11/z_sub.c
case '?':
if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'l' || optopt == 'n') {
if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'l' || optopt == 'n' ||
optopt == 't') {
Comment thread src/transport/manager.c
const _z_config_t *config) {
if (!_z_pending_peers_has_pending(pending_peers)) {
const _z_config_t *config, size_t max_attempts) {
size_t pending_count = _z_pending_peers_count_pending(pending_peers);
Comment thread src/transport/manager.c

for (size_t attempt = 0; attempt < loop_count; attempt++) {
size_t i = 0;
if (!_z_pending_peers_next_pending_idx(pending_peers, &i)) {
Comment thread src/transport/manager.c Fixed
Comment thread src/transport/manager.c Outdated
gmartin82 added 2 commits May 15, 2026 11:25
In single-thread mode, spin the async-opened session from only one test thread while waiting for peer discovery, avoiding concurrent zp_spin_once() calls on the same session.
Limit the background add-peers task to a small number of peer attempts per executor tick, rotating through pending locators before applying backoff. This prevents peer retry work from monopolizing single-thread runtimes while still retrying the full pending set before sleeping.
Comment thread src/transport/manager.c
}

#if Z_FEATURE_UNICAST_PEER == 1
#define _Z_ADD_PEERS_ALL_PENDING 0
Comment thread src/transport/manager.c

#if Z_FEATURE_UNICAST_PEER == 1
#define _Z_ADD_PEERS_ALL_PENDING 0
#define _Z_ADD_PEERS_TASK_MAX_ATTEMPTS 1
Comment thread src/transport/manager.c
// Non-retryable error
bool has_pending = _z_pending_peers_has_pending(pending_peers);

if (result._last_non_retryable_ret != _Z_RES_OK) {
Comment thread src/transport/manager.c

if (result._last_non_retryable_ret != _Z_RES_OK) {
// Non-retryable error.
if (exit_on_failure) {
Comment thread src/transport/manager.c
_z_pending_peers_clear(pending_peers);
return _Z_RES_OK;
}

Comment thread src/transport/manager.c
if (pending_peers->_remaining_attempts == 0) {
pending_peers->_remaining_attempts = _z_pending_peers_count_pending(pending_peers);
}

Comment thread src/transport/manager.c
if (pending_peers->_remaining_attempts > 0) {
return _z_fut_fn_result_continue();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Changes not included in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants