@@ -1,3 +1,78 @@
|
||||
// Example 05 — Error Handling & Diagnostics
|
||||
//
|
||||
// Demonstrates observable failure modes and the diagnostics system:
|
||||
//
|
||||
// 1. ChannelOverflowError — a fast producer saturates a slow consumer.
|
||||
// When the channel is full, push() throws ChannelOverflowError.
|
||||
// The node's run_loop catches it and prints to stderr.
|
||||
// Channel statistics (overflows, peak fill) accumulate for the report.
|
||||
//
|
||||
// 2. Custom diagnostics handler — instead of the default periodic table,
|
||||
// install a handler that surfaces only the metrics you care about.
|
||||
//
|
||||
// 3. net.print_diagnostics() — print a full report at any time.
|
||||
//
|
||||
// Pipeline: [producer] --int--> [slow_consumer]
|
||||
|
||||
#include <kpn/kpn.hpp>
|
||||
// TODO: implement example
|
||||
int main() { return 0; }
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
// ── Node functions ────────────────────────────────────────────────────────────
|
||||
|
||||
// Produces at ~100/s — faster than the consumer can keep up (50 ms each)
|
||||
static int producer() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
static int n = 0;
|
||||
return ++n;
|
||||
}
|
||||
|
||||
// Slow consumer: 50 ms per item — will cause channel to fill and overflow
|
||||
static void slow_consumer(int x) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
std::cout << "[consumed] " << x << '\n';
|
||||
}
|
||||
|
||||
// ── main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
int main() {
|
||||
using namespace kpn;
|
||||
|
||||
// Capacity=4: fills up quickly when producer outpaces consumer 5:1
|
||||
auto prod = make_node<producer> (out<"v">{}, /*capacity=*/4);
|
||||
auto cons = make_node<slow_consumer> (in<"v">{}, /*capacity=*/4);
|
||||
|
||||
Network net;
|
||||
|
||||
// Custom diagnostics handler — fires on the watchdog interval.
|
||||
// Print a concise one-liner rather than the full table.
|
||||
net.set_diagnostics_handler([](const std::vector<NodeSnapshot>& nodes,
|
||||
const std::vector<ChannelSnapshot>& channels) {
|
||||
std::cout << "[diag] ";
|
||||
for (auto& n : nodes)
|
||||
std::cout << n.name << "=" << n.throughput_fps << "fps ";
|
||||
for (auto& c : channels)
|
||||
std::cout << "channel fill=" << static_cast<int>(c.fill_pct()) << "% "
|
||||
<< "overflows=" << c.overflows;
|
||||
std::cout << '\n';
|
||||
});
|
||||
|
||||
net.set_watchdog_interval(std::chrono::milliseconds(200));
|
||||
|
||||
net.add("prod", prod)
|
||||
.add("cons", cons)
|
||||
.connect("prod", prod.template output<"v">(), "cons", cons.template input<"v">())
|
||||
.build();
|
||||
|
||||
std::cout << "producer: 10ms/item, consumer: 50ms/item, capacity=4\n"
|
||||
<< "Overflow messages appear on stderr; diagnostics on stdout.\n\n";
|
||||
|
||||
net.start();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(800));
|
||||
net.stop();
|
||||
|
||||
// Full report after shutdown — overflow and drop counts are preserved
|
||||
std::cout << '\n';
|
||||
net.print_diagnostics();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user