Performance improvements, better readme and complete python bindings
🧪 Test / test (push) Failing after 28m30s
🧪 Test / test (push) Failing after 28m30s
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
#include "channel.hpp"
|
||||
#include "diagnostics.hpp"
|
||||
#include "fanout.hpp"
|
||||
#include "node.hpp"
|
||||
#include "inode.hpp"
|
||||
#include "port.hpp"
|
||||
#include "tmp/fanout_groups.hpp"
|
||||
#include "tmp/topo_sort.hpp"
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -75,6 +76,10 @@ std::string node_display_name() {
|
||||
return std::string(lbl);
|
||||
} else if constexpr (requires { NodeT::is_fanout_node; NodeT::unique_tag; }) {
|
||||
return "fanout[" + std::to_string(NodeT::unique_tag) + "]";
|
||||
} else if constexpr (requires { NodeT::is_router_node; NodeT::unique_tag; }) {
|
||||
return "router[" + std::to_string(NodeT::unique_tag) + "]";
|
||||
} else if constexpr (requires { NodeT::is_filter_node; NodeT::unique_tag; }) {
|
||||
return "filter[" + std::to_string(NodeT::unique_tag) + "]";
|
||||
} else if constexpr (requires { NodeT::unique_tag; }) {
|
||||
return "node[" + std::to_string(NodeT::unique_tag) + "]";
|
||||
} else {
|
||||
@@ -115,7 +120,7 @@ public:
|
||||
web_debug_port_,
|
||||
[this]() {
|
||||
auto s = collect_snapshots();
|
||||
return web_debug::to_json(s.nodes, s.channels, s.resources, s.elapsed_s);
|
||||
return web_debug::to_json(s.nodes, s.channels, s.resources, s.elapsed_s, s.pools);
|
||||
});
|
||||
web_server_->start();
|
||||
std::cerr << "[kpn] web debug UI: http://localhost:" << web_debug_port_ << "\n";
|
||||
@@ -123,7 +128,9 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop() override {
|
||||
void stop() override { halt(); }
|
||||
|
||||
void halt() override {
|
||||
stop_flag_ = true;
|
||||
#ifdef KPN_WEB_DEBUG
|
||||
if (web_server_) web_server_->stop();
|
||||
@@ -134,6 +141,22 @@ public:
|
||||
(*it)->stop();
|
||||
}
|
||||
|
||||
// shutdown(): graceful drain in topological order (sources first).
|
||||
// Stops source nodes, polls channels until empty, then stops each downstream layer.
|
||||
void shutdown() override {
|
||||
stop_flag_ = true;
|
||||
#ifdef KPN_WEB_DEBUG
|
||||
if (web_server_) web_server_->stop();
|
||||
#endif
|
||||
// user_nodes_topo_ is already in sources-first order.
|
||||
// Stop each node and drain its output channels before moving on.
|
||||
for (auto* n : user_nodes_topo_) {
|
||||
n->stop();
|
||||
drain_all_channels();
|
||||
}
|
||||
for (auto* n : fanout_nodes_ptr_) n->stop();
|
||||
}
|
||||
|
||||
bool running() const override { return !stop_flag_; }
|
||||
|
||||
void set_name(std::string name) override { name_ = std::move(name); }
|
||||
@@ -160,6 +183,12 @@ public:
|
||||
resource_probes_.emplace_back(name, probe);
|
||||
}
|
||||
|
||||
// Register a thread pool so it appears in diagnostics and the debug UI.
|
||||
// The probe must outlive this network (typically the pool is on the same stack/shared_ptr).
|
||||
void register_pool(const std::string& name, IPoolProbe* probe) {
|
||||
pool_probes_.emplace_back(name, probe);
|
||||
}
|
||||
|
||||
// Print diagnostics using compile-time node labels
|
||||
void print_diagnostics(std::ostream& os = std::cerr) const {
|
||||
os << "\n┌─ KPN++ StaticNetwork diagnostics ─────────────────────────────\n";
|
||||
@@ -179,6 +208,7 @@ private:
|
||||
std::vector<NodeSnapshot> nodes;
|
||||
std::vector<ChannelSnapshot> channels;
|
||||
std::vector<ResourceSnapshot> resources;
|
||||
std::vector<PoolSnapshot> pools;
|
||||
double elapsed_s;
|
||||
};
|
||||
|
||||
@@ -200,7 +230,23 @@ private:
|
||||
for (auto& [name, probe] : resource_probes_)
|
||||
resources.push_back(probe->snapshot(name));
|
||||
|
||||
return {std::move(nodes), std::move(channels), std::move(resources), elapsed_s};
|
||||
std::vector<PoolSnapshot> pools;
|
||||
for (auto& [name, probe] : pool_probes_)
|
||||
pools.push_back(probe->snapshot(name));
|
||||
|
||||
return {std::move(nodes), std::move(channels), std::move(resources), std::move(pools), elapsed_s};
|
||||
}
|
||||
|
||||
void drain_all_channels() const {
|
||||
bool any_full = true;
|
||||
while (any_full) {
|
||||
any_full = false;
|
||||
for (auto& probe : channel_probes_) {
|
||||
if (probe->snapshot().current_fill > 0) { any_full = true; break; }
|
||||
}
|
||||
if (any_full)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
std::string name_;
|
||||
@@ -212,6 +258,7 @@ private:
|
||||
std::vector<std::string> fanout_node_names_;
|
||||
std::vector<std::unique_ptr<IChannelProbe>> channel_probes_;
|
||||
std::vector<std::pair<std::string, IResourceProbe*>> resource_probes_;
|
||||
std::vector<std::pair<std::string, IPoolProbe*>> pool_probes_;
|
||||
clock_t::time_point start_time_;
|
||||
#ifdef KPN_WEB_DEBUG
|
||||
uint16_t web_debug_port_{9090};
|
||||
|
||||
Reference in New Issue
Block a user