Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 19 additions & 36 deletions .github/workflows/reusable/cached-install/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,18 @@ description: "install dependencies, build and cache result, or restore from cach
runs:
using: "composite"
steps:
# The cache keys must distinguish the TARGET platform, not just the
# runner: the macOS host build, the iOS build and the Android build
# all run on the same macos runner image, and GitHub's cache is
# write-once per key — with a shared key the first job to save owns
# the cache forever and the other platforms' saves fail ("Cache save
# failed."), so their dependencies were rebuilt from source on every
# run (~30 min Android, ~35 min iOS). ARCHFLAGS is the workflow-level
# platform selector (empty = host, --ios, --android). The vcpkg
# submodule commit is part of the key because the tool version
# changes what it builds; the restore-keys prefix fallback reuses the
# newest previous cache on any key miss — vcpkg's own per-package ABI
# hashing makes stale archive entries harmless (they are ignored) and
# `vcpkg install` reconciles a stale installed tree.
- name: compute cache keys
id: keys
run: |
echo "platform=${ARCHFLAGS:-host}" >> "$GITHUB_OUTPUT"
echo "vcpkg_sha=$(git rev-parse HEAD:vcpkg)" >> "$GITHUB_OUTPUT"
shell: bash
- name: cache vcpkg binary archives
- name: cache homedir
id: cache-homedir
uses: actions/cache/restore@v4
with:
key: ${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-archives-${{ steps.keys.outputs.vcpkg_sha }}-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
restore-keys: |
${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-archives-${{ steps.keys.outputs.vcpkg_sha }}-
${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-archives-
key: ${{ runner.arch }}-${{ runner.os }}-cache-homedir2-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
path: |
~/.cache/vcpkg/archives
- name: cache vcpkg installed
id: cache-vcpkg-installed
uses: actions/cache/restore@v4
with:
key: ${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-installed-${{ steps.keys.outputs.vcpkg_sha }}-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
restore-keys: |
${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-installed-${{ steps.keys.outputs.vcpkg_sha }}-
${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-installed-
key: ${{ runner.arch }}-${{ runner.os }}-cache-vcpkg-installed2-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
path: |
./build/vcpkg_installed
- name: install-prerequisities
Expand Down Expand Up @@ -70,22 +45,30 @@ runs:
exit "$EXITCODE"
fi
shell: bash
# Save even on failure (if: always()) so a partially built dependency
# set is reused by the retry. Saving is skipped when the exact key was
# already restored (nothing new to store).
- name: cache vcpkg binary archives save
- name: cache homedir save
id: cache-homedir-save
if: always() && steps.cache-homedir.outputs.cache-hit != 'true'
if: always()
uses: actions/cache/save@v4
with:
key: ${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-archives-${{ steps.keys.outputs.vcpkg_sha }}-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
key: ${{ runner.arch }}-${{ runner.os }}-cache-homedir2-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
path: |
~/.cache/vcpkg/archives
- name: cache vcpkg installed save
id: cache-vcpkg-installed-save
if: always() && steps.cache-vcpkg-installed.outputs.cache-hit != 'true'
if: always()
uses: actions/cache/save@v4
with:
key: ${{ runner.arch }}-${{ runner.os }}-${{ steps.keys.outputs.platform }}-installed-${{ steps.keys.outputs.vcpkg_sha }}-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
key: ${{ runner.arch }}-${{ runner.os }}-cache-vcpkg-installed2-${{ hashFiles('./vcpkg.json', './overlaytriplets/**', './overlayports/**') }}
path: |
./build/vcpkg_installed
#- name: Commit compiled binaries
# run: |
# git config --global user.name 'github-actions[bot]'
# git config --global user.email 'github-actions[bot]@users.noreply.github.com'
# git add packages/streamr-libstreamrproxyclient/dist
# git add packages/streamr-libstreamrproxyclient/wrappers/go
# git commit -m "Automatically compiled binaries"
# git pull --rebase --no-edit
# git push --no-verify
# shell: bash

23 changes: 22 additions & 1 deletion MODERNIZATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,28 @@ exactly that. So consolidation walks the dependency chain from the top:
build + 15/15 tests, standalone package build, package lint green
(two bugprone-exception-escape suppressions — the checker cannot see
through imported module interfaces; known pattern).
2. C-2 streamr-trackerless-network
2. **C-2 streamr-trackerless-network** ✅ — **OWNER DIRECTIVE
(2026-07-04): one partition file per former header, never one merged
file.** Each of the 13 public headers (1,704 lines) became its own
partition `modules/streamr.trackerlessnetwork-<Name>.cppm`
(`export module streamr.trackerlessnetwork:<Name>;`), with only that
header's third-party/std/generated includes in its global module
fragment, `import :<Dep>;` for the old intra-package include edges,
`import streamr.<pkg>;` for sibling packages, and its content in
`export namespace` blocks (export-using of module-linkage entities
is ill-formed — declarations are exported directly). The coarse
`:all` partition is gone; the primary unit re-exports every
partition. The include/ tree is deleted. Gotcha found twice: a
partition must textually include what ITS code uses (std::operator+
from <string>, folly::coro::blockingWait) — the former headers
received these transitively from neighbors, and entities reached
only through an imported module's global module fragment are not
reliably reachable. The last textually-including test file
(ProxyClientTsIntegrationTest.cpp) flipped to imports. Lint posture
IMPROVED: clangd-tidy now runs on all 15 module units — full
analysis coverage, zero suppressions. Verified: Release build, tn
tests 12+1, proxyclient importer 15/15, standalone builds, lint
green.
3. C-3 streamr-dht (the largest)
4. C-4 streamr-proto-rpc
5. C-5 streamr-utils
Expand Down
31 changes: 20 additions & 11 deletions packages/streamr-trackerless-network/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,19 @@ add_library(streamr-trackerless-network)
set_property(TARGET streamr-trackerless-network PROPERTY CXX_STANDARD 26)
add_library(streamr::streamr-trackerless-network ALIAS streamr-trackerless-network)

# Module façade (MODERNIZATION.md Part 2): :protos over the generated
# NetworkRpc trio + one coarse :all partition over the public headers.
# CONSOLIDATED (MODERNIZATION.md Phase 2.6): one partition per former
# public header, in the same directory tree the headers had (the
# partition files are the source of truth), plus :protos over the
# generated NetworkRpc trio and the primary interface unit that
# re-exports every partition.
file(GLOB_RECURSE TRACKERLESS_NETWORK_MODULE_UNITS CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/modules/*.cppm)
streamr_target_module_sources(streamr-trackerless-network
FILES
modules/streamr.trackerlessnetwork.cppm
modules/streamr.trackerlessnetwork-protos.cppm
modules/streamr.trackerlessnetwork-all.cppm)
target_include_directories(streamr-trackerless-network
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PUBLIC $<INSTALL_INTERFACE:include>
FILES ${TRACKERLESS_NETWORK_MODULE_UNITS})
# CONSOLIDATED: the include/ tree is gone (the code lives in the module
# units); only the generated protobuf code remains a header consumers
# may need textually.
target_include_directories(streamr-trackerless-network
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/proto>
)

Expand Down Expand Up @@ -151,10 +154,16 @@ if(NOT IOS AND STREAMR_MODULES_SUPPORTED)
add_executable(streamr-trackerless-network-test-integration
test/integration/ProxyClientTsIntegrationTest.cpp
)
# The test imports modules, so its source needs module dependency
# scanning; imported modules are usable only by DIRECT consumers, so
# every directly-imported module is linked here.
streamr_enable_imports(streamr-trackerless-network-test-integration)

target_link_libraries(streamr-trackerless-network-test-integration
target_link_libraries(streamr-trackerless-network-test-integration
PUBLIC streamr-trackerless-network
INTERFACE streamr::streamr-logger
PUBLIC streamr::streamr-dht
PUBLIC streamr::streamr-logger
PUBLIC streamr::streamr-utils
PUBLIC GTest::gtest
PUBLIC streamr-trackerless-network-test-main
)
Expand Down

This file was deleted.

19 changes: 8 additions & 11 deletions packages/streamr-trackerless-network/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@ clangd-tidy -p ./build $TESTFILES
echo "Running clang-format --dry-run on $TESTFILES"
../../run-clang-format.py $TESTFILES

INCLUDEFILES=$(find include -type f \( -name "*.hpp" -o -name "*.cpp" \) -not -path '*/proto/*' | sort | uniq | tr '\n' ' ')
echo "Running clangd-tidy on $INCLUDEFILES"

clangd-tidy -p ./build $INCLUDEFILES

echo "Running clang-format --dry-run on $INCLUDEFILES"
../../run-clang-format.py $INCLUDEFILES

# Module interface units: format check only. clangd-tidy is not run on
# .cppm files (headers remain the fully linted source of truth during the
# façade migration; clangd modules support is still experimental).
# CONSOLIDATED (MODERNIZATION.md Phase 2.6): the include/ tree is gone —
# the code lives in the module interface units, which are now linted
# with clangd-tidy as the source of truth (verified working with clangd
# 22; the consolidated units carry no export-using re-export blocks,
# which were the source of the earlier false positives).
MODULE_FILES=$(find ./modules -type f -name "*.cppm" 2>/dev/null | xargs echo)
if [ -n "$MODULE_FILES" ]; then
echo "Running clangd-tidy on $MODULE_FILES"
clangd-tidy -p ./build $MODULE_FILES

echo "Running clang-format --dry-run on $MODULE_FILES"
../../run-clang-format.py $MODULE_FILES
fi
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
#ifndef STREAMR_TRACKERLESS_NETWORK_CONTENT_DELIVERY_RPC_LOCAL_HPP
#define STREAMR_TRACKERLESS_NETWORK_CONTENT_DELIVERY_RPC_LOCAL_HPP
// Module partition streamr.trackerlessnetwork:ContentDeliveryRpcLocal
// CONSOLIDATED from the former header logic/ContentDeliveryRpcLocal.hpp
// (MODERNIZATION.md Phase 2.6): this file is now the source of truth.
module;

#include "packages/dht/protos/DhtRpc.pb.h"
#include "packages/network/protos/NetworkRpc.pb.h"
#include "packages/network/protos/NetworkRpc.server.pb.h"
#include "streamr-dht/Identifiers.hpp"
#include "streamr-dht/rpc-protocol/DhtCallContext.hpp"
#include "streamr-dht/transport/ListeningRpcCommunicator.hpp"
#include "streamr-utils/StreamPartID.hpp"

namespace streamr::trackerlessnetwork {
export module streamr.trackerlessnetwork:ContentDeliveryRpcLocal;

using ::dht::PeerDescriptor;
import streamr.dht;
import streamr.utils;

// Hoisted from the former header (file scope, NOT exported);
// fully qualified because relative namespace names resolve
// differently at file scope than inside the package namespace.
using streamr::dht::DhtAddress;
using streamr::dht::Identifiers;
using streamr::dht::rpcprotocol::DhtCallContext;
using streamr::dht::transport::ListeningRpcCommunicator;
using streamr::utils::StreamPartID;
export namespace streamr::trackerlessnetwork {

using ::dht::PeerDescriptor;
using ContentDeliveryRpc =
::streamr::protorpc::ContentDeliveryRpc<DhtCallContext>;

Expand Down Expand Up @@ -64,5 +70,3 @@ class ContentDeliveryRpcLocal : public ContentDeliveryRpc {
};

} // namespace streamr::trackerlessnetwork

#endif // STREAMR_TRACKERLESS_NETWORK_CONTENT_DELIVERY_RPC_LOCAL_HPP
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
#ifndef STREAMR_TRACKERLESS_NETWORK_CONTENT_DELIVERY_RPC_REMOTE_HPP
#define STREAMR_TRACKERLESS_NETWORK_CONTENT_DELIVERY_RPC_REMOTE_HPP
// Module partition streamr.trackerlessnetwork:ContentDeliveryRpcRemote
// CONSOLIDATED from the former header logic/ContentDeliveryRpcRemote.hpp
// (MODERNIZATION.md Phase 2.6): this file is now the source of truth.
module;

#include <string>
#include <folly/experimental/coro/Task.h>
#include "packages/dht/protos/DhtRpc.pb.h"
#include "packages/network/protos/NetworkRpc.client.pb.h"
#include "packages/network/protos/NetworkRpc.pb.h"
#include "streamr-dht/dht/contact/RpcRemote.hpp"
#include "streamr-dht/rpc-protocol/DhtCallContext.hpp"
#include "streamr-logger/SLogger.hpp"
#include "streamr-utils/StreamPartID.hpp"

namespace streamr::trackerlessnetwork {
export module streamr.trackerlessnetwork:ContentDeliveryRpcRemote;

using ::dht::PeerDescriptor;
import streamr.dht;
import streamr.logger;
import streamr.utils;

// Hoisted from the former header (file scope, NOT exported);
// fully qualified because relative namespace names resolve
// differently at file scope than inside the package namespace.
using streamr::dht::contact::RpcRemote;
using streamr::dht::rpcprotocol::DhtCallContext;
using streamr::logger::SLogger;
using streamr::utils::StreamPartID;
export namespace streamr::trackerlessnetwork {

using ::dht::PeerDescriptor;
using ContentDeliveryRpcClient =
streamr::protorpc::ContentDeliveryRpcClient<DhtCallContext>;
using streamr::utils::StreamPartID;
class ContentDeliveryRpcRemote : public RpcRemote<ContentDeliveryRpcClient> {
public:
ContentDeliveryRpcRemote(
Expand Down Expand Up @@ -62,5 +69,3 @@ class ContentDeliveryRpcRemote : public RpcRemote<ContentDeliveryRpcClient> {
};

} // namespace streamr::trackerlessnetwork

#endif
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#ifndef STREAMR_TRACKERLESS_NETWORK_DUPLICATE_MESSAGE_DETECTOR_HPP
#define STREAMR_TRACKERLESS_NETWORK_DUPLICATE_MESSAGE_DETECTOR_HPP
// Module partition streamr.trackerlessnetwork:DuplicateMessageDetector
// CONSOLIDATED from the former header logic/DuplicateMessageDetector.hpp
// (MODERNIZATION.md Phase 2.6): this file is now the source of truth.
module;

#include <optional>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "streamr-logger/SLogger.hpp"
namespace streamr::trackerlessnetwork {

export module streamr.trackerlessnetwork:DuplicateMessageDetector;

import streamr.logger;

// Hoisted from the former header (file scope, NOT exported);
// fully qualified because relative namespace names resolve
// differently at file scope than inside the package namespace.
using streamr::logger::SLogger;
export namespace streamr::trackerlessnetwork {

/**
* Represent a pair of numbers (a,b). Ordering between two pairs is defined as
Expand Down Expand Up @@ -215,5 +223,3 @@ class DuplicateMessageDetector {
};

} // namespace streamr::trackerlessnetwork

#endif // STREAMR_TRACKERLESS_NETWORK_DUPLICATE_MESSAGE_DETECTOR_HPP
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
#ifndef STREAMR_TRACKERLESS_NETWORK_NODE_LIST_HPP
#define STREAMR_TRACKERLESS_NETWORK_NODE_LIST_HPP
// Module partition streamr.trackerlessnetwork:NodeList
// CONSOLIDATED from the former header logic/NodeList.hpp
// (MODERNIZATION.md Phase 2.6): this file is now the source of truth.
module;

#include <map>
#include <ranges>
#include <vector>
#include "streamr-dht/Identifiers.hpp"
#include "streamr-eventemitter/EventEmitter.hpp"
#include "streamr-trackerless-network/logic/ContentDeliveryRpcRemote.hpp"

namespace streamr::trackerlessnetwork {
export module streamr.trackerlessnetwork:NodeList;

import streamr.dht;
import streamr.eventemitter;
import :ContentDeliveryRpcRemote;

// Hoisted from the former header (file scope, NOT exported);
// fully qualified because relative namespace names resolve
// differently at file scope than inside the package namespace.
using streamr::dht::DhtAddress;
using streamr::dht::Identifiers;
using streamr::eventemitter::Event;
using streamr::eventemitter::EventEmitter;
export namespace streamr::trackerlessnetwork {

class ContentDeliveryRpcRemote;
struct NodeAdded
Expand Down Expand Up @@ -178,5 +185,3 @@ class NodeList : public EventEmitter<NodeListEvents> {
};

} // namespace streamr::trackerlessnetwork

#endif // STREAMR_TRACKERLESS_NETWORK_NODE_LIST_HPP
Loading
Loading