@@ -1,3 +1,90 @@
|
||||
// Example 06 — Watchdog & Diagnostics (+ optional web debug UI)
|
||||
//
|
||||
// A four-stage pipeline with deliberately uneven node speeds:
|
||||
//
|
||||
// [source] --int--> [fast_filter] --int--> [slow_transform] --int--> [sink]
|
||||
//
|
||||
// The watchdog fires every second and prints a full diagnostics report:
|
||||
// - frames processed, throughput fps, exec time, blocked time per node
|
||||
// - channel fill %, peak fill %, pushes, overflows, bandwidth
|
||||
// - bottleneck hint (node with highest avg exec time)
|
||||
//
|
||||
// "slow_transform" sleeps 30 ms per item, making it the obvious bottleneck.
|
||||
// Watch the channel upstream of it saturate and the fps converge to ~33.
|
||||
//
|
||||
// Build with -DKPN_WEB_DEBUG=ON to also get a live D3 graph at localhost:9090.
|
||||
|
||||
#include <kpn/kpn.hpp>
|
||||
// TODO: implement example
|
||||
int main() { return 0; }
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
// ── Node functions ────────────────────────────────────────────────────────────
|
||||
|
||||
static int source() {
|
||||
// Produces at ~50 fps — faster than slow_transform (33 fps) so the
|
||||
// channel between filter and slow gradually fills, but not catastrophically
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
static int n = 0;
|
||||
return ++n;
|
||||
}
|
||||
|
||||
static int fast_filter(int x) {
|
||||
// Trivial work: ~0.1 ms
|
||||
return (x % 2 == 0) ? x : x + 1;
|
||||
}
|
||||
|
||||
static int slow_transform(int x) {
|
||||
// Simulates expensive processing (e.g. a neural net inference step)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||
return x * x;
|
||||
}
|
||||
|
||||
static void sink(int x) {
|
||||
// Print every 10th result to avoid flooding the terminal
|
||||
if (x % 100 < 4)
|
||||
std::cout << "[sink] " << x << '\n';
|
||||
}
|
||||
|
||||
// ── main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
int main() {
|
||||
using namespace kpn;
|
||||
|
||||
// Larger capacity buffers so the fast nodes don't immediately overflow
|
||||
auto src = make_node<source> (out<"v">{}, 16);
|
||||
auto filt = make_node<fast_filter> (in<"v">{}, out<"v">{}, 16);
|
||||
auto slow = make_node<slow_transform> (in<"v">{}, out<"v">{}, 8);
|
||||
auto snk = make_node<sink> (in<"v">{}, 8);
|
||||
|
||||
Network net;
|
||||
|
||||
// Watchdog fires every 1 second — prints the built-in diagnostics table
|
||||
// including the "Bottleneck hint" line
|
||||
net.set_watchdog_interval(std::chrono::milliseconds(1000));
|
||||
|
||||
net.add("source", src)
|
||||
.add("filter", filt)
|
||||
.add("slow", slow)
|
||||
.add("sink", snk)
|
||||
.connect("source", src.template output<"v">(), "filter", filt.template input<"v">())
|
||||
.connect("filter", filt.template output<"v">(), "slow", slow.template input<"v">())
|
||||
.connect("slow", slow.template output<"v">(), "sink", snk.template input<"v">())
|
||||
.build();
|
||||
|
||||
std::cout << "Running for 30 seconds — watch 'slow' become the bottleneck.\n"
|
||||
<< "Watchdog diagnostics print every 1 second.\n";
|
||||
#ifdef KPN_WEB_DEBUG
|
||||
net.set_web_debug_port(9090);
|
||||
std::cout << "Web debug UI: http://localhost:9090 (live graph, auto-updates every 500 ms)\n";
|
||||
#endif
|
||||
std::cout << '\n';
|
||||
|
||||
net.start();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(30));
|
||||
net.stop();
|
||||
|
||||
std::cout << "\n=== Final diagnostics ===\n";
|
||||
net.print_diagnostics();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user