Added callbacks for node errors and fifo overflow
Add new doc system which should/might deploy to pages.
This commit is contained in:
+86
-39
@@ -101,6 +101,11 @@ public:
|
||||
void set_error_handler(NodeErrorHandler h) { error_handler_ = std::move(h); }
|
||||
void set_max_exec_time(std::chrono::milliseconds t) { max_exec_time_ = t; }
|
||||
|
||||
void set_overflow_callback(NodeEventCallback cb) { event_callbacks_[0] = std::move(cb); }
|
||||
void set_network_overflow_callback(NodeEventCallback cb) override { event_callbacks_[1] = std::move(cb); }
|
||||
void set_closed_callback(NodeEventCallback cb) { closed_callbacks_[0] = std::move(cb); }
|
||||
void set_network_closed_callback(NodeEventCallback cb) override { closed_callbacks_[1] = std::move(cb); }
|
||||
|
||||
const NodeStats& stats() const override { return stats_; }
|
||||
|
||||
NodeSnapshot node_snapshot(const std::string& name, double elapsed_s) const override {
|
||||
@@ -189,12 +194,31 @@ private:
|
||||
(std::get<Is>(input_channels_)->disable(), ...);
|
||||
}
|
||||
|
||||
template<std::size_t... Is>
|
||||
void disable_outputs(std::index_sequence<Is...>) {
|
||||
auto disable_one = [](auto* ch) { if (ch) ch->disable(); };
|
||||
(disable_one(std::get<Is>(output_channels_)), ...);
|
||||
}
|
||||
|
||||
template<std::size_t... Is>
|
||||
void register_callbacks(std::index_sequence<Is...>) {
|
||||
(std::get<Is>(input_channels_)->set_push_callback(
|
||||
[this] { on_input_ready(); }), ...);
|
||||
}
|
||||
|
||||
static void fire_callbacks(const std::array<NodeEventCallback, 2>& cbs) {
|
||||
const auto ts = std::chrono::steady_clock::now();
|
||||
for (auto& cb : cbs) if (cb) cb(ts);
|
||||
}
|
||||
|
||||
void self_stop() {
|
||||
disable_inputs(std::make_index_sequence<input_count>{});
|
||||
disable_outputs(std::make_index_sequence<output_count>{});
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
template<typename Tup, std::size_t... Is>
|
||||
static auto make_input_channel_tuple(std::index_sequence<Is...>)
|
||||
-> std::tuple<std::shared_ptr<Channel<std::tuple_element_t<Is, Tup>>>...>;
|
||||
@@ -278,19 +302,17 @@ private:
|
||||
// blocked_time = 0 for pool nodes (we don't block waiting for inputs)
|
||||
stats_.record_exec(duration_t(t2 - t1), duration_t::zero(), cpu0, cpu1);
|
||||
} catch (const ChannelClosedError&) {
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
fire_callbacks(closed_callbacks_);
|
||||
self_stop();
|
||||
return;
|
||||
} catch (const ChannelOverflowError& e) {
|
||||
std::cerr << "[kpn] pool overflow: " << e.what() << "\n";
|
||||
} catch (const ChannelOverflowError&) {
|
||||
fire_callbacks(event_callbacks_);
|
||||
} catch (...) {
|
||||
if (error_handler_ && error_handler_(name_, std::current_exception())) {
|
||||
// continue — fall through to resubmit check
|
||||
} else {
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
fire_callbacks(closed_callbacks_);
|
||||
self_stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -359,16 +381,18 @@ private:
|
||||
|
||||
// ── State ─────────────────────────────────────────────────────────────────
|
||||
|
||||
std::shared_ptr<IScheduler> scheduler_;
|
||||
std::string name_;
|
||||
std::size_t fifo_capacity_;
|
||||
input_channels_t input_channels_;
|
||||
output_channels_t output_channels_{};
|
||||
std::atomic<bool> stop_flag_{true};
|
||||
std::atomic<bool> queued_{false};
|
||||
NodeStats stats_;
|
||||
NodeErrorHandler error_handler_;
|
||||
std::chrono::milliseconds max_exec_time_{0};
|
||||
std::shared_ptr<IScheduler> scheduler_;
|
||||
std::string name_;
|
||||
std::size_t fifo_capacity_;
|
||||
input_channels_t input_channels_;
|
||||
output_channels_t output_channels_{};
|
||||
std::atomic<bool> stop_flag_{true};
|
||||
std::atomic<bool> queued_{false};
|
||||
NodeStats stats_;
|
||||
NodeErrorHandler error_handler_;
|
||||
std::chrono::milliseconds max_exec_time_{0};
|
||||
std::array<NodeEventCallback, 2> event_callbacks_{}; // [0]=user [1]=network
|
||||
std::array<NodeEventCallback, 2> closed_callbacks_{};
|
||||
};
|
||||
|
||||
// ── PoolObjectNode ────────────────────────────────────────────────────────────
|
||||
@@ -435,6 +459,11 @@ public:
|
||||
void set_error_handler(NodeErrorHandler h) { error_handler_ = std::move(h); }
|
||||
void set_max_exec_time(std::chrono::milliseconds t) { max_exec_time_ = t; }
|
||||
|
||||
void set_overflow_callback(NodeEventCallback cb) { event_callbacks_[0] = std::move(cb); }
|
||||
void set_network_overflow_callback(NodeEventCallback cb) override { event_callbacks_[1] = std::move(cb); }
|
||||
void set_closed_callback(NodeEventCallback cb) { closed_callbacks_[0] = std::move(cb); }
|
||||
void set_network_closed_callback(NodeEventCallback cb) override { closed_callbacks_[1] = std::move(cb); }
|
||||
|
||||
const NodeStats& stats() const override { return stats_; }
|
||||
|
||||
NodeSnapshot node_snapshot(const std::string& name, double elapsed_s) const override {
|
||||
@@ -490,13 +519,31 @@ private:
|
||||
std::make_shared<Channel<std::tuple_element_t<Is, args_tuple>>>(fifo_capacity_)),
|
||||
...);
|
||||
}
|
||||
template<std::size_t... Is> void enable_inputs(std::index_sequence<Is...>) { (std::get<Is>(input_channels_)->enable(), ...); }
|
||||
template<std::size_t... Is> void disable_inputs(std::index_sequence<Is...>) { (std::get<Is>(input_channels_)->disable(), ...); }
|
||||
template<std::size_t... Is> void enable_inputs(std::index_sequence<Is...>) { (std::get<Is>(input_channels_)->enable(), ...); }
|
||||
template<std::size_t... Is> void disable_inputs(std::index_sequence<Is...>) { (std::get<Is>(input_channels_)->disable(), ...); }
|
||||
template<std::size_t... Is>
|
||||
void disable_outputs(std::index_sequence<Is...>) {
|
||||
auto disable_one = [](auto* ch) { if (ch) ch->disable(); };
|
||||
(disable_one(std::get<Is>(output_channels_)), ...);
|
||||
}
|
||||
template<std::size_t... Is>
|
||||
void register_callbacks(std::index_sequence<Is...>) {
|
||||
(std::get<Is>(input_channels_)->set_push_callback([this] { on_input_ready(); }), ...);
|
||||
}
|
||||
|
||||
static void fire_callbacks(const std::array<NodeEventCallback, 2>& cbs) {
|
||||
const auto ts = std::chrono::steady_clock::now();
|
||||
for (auto& cb : cbs) if (cb) cb(ts);
|
||||
}
|
||||
|
||||
void self_stop() {
|
||||
disable_inputs(std::make_index_sequence<input_count>{});
|
||||
disable_outputs(std::make_index_sequence<output_count>{});
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
template<typename Tup, std::size_t... Is>
|
||||
static auto make_input_channel_tuple(std::index_sequence<Is...>)
|
||||
-> std::tuple<std::shared_ptr<Channel<std::tuple_element_t<Is, Tup>>>...>;
|
||||
@@ -567,18 +614,16 @@ private:
|
||||
auto t2 = clock_t::now();
|
||||
stats_.record_exec(duration_t(t2 - t1), duration_t::zero(), cpu0, cpu1);
|
||||
} catch (const ChannelClosedError&) {
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
fire_callbacks(closed_callbacks_);
|
||||
self_stop();
|
||||
return;
|
||||
} catch (const ChannelOverflowError& e) {
|
||||
std::cerr << "[kpn] pool overflow: " << e.what() << "\n";
|
||||
} catch (const ChannelOverflowError&) {
|
||||
fire_callbacks(event_callbacks_);
|
||||
} catch (...) {
|
||||
if (error_handler_ && error_handler_(name_, std::current_exception())) {
|
||||
} else {
|
||||
stats_.exec_start_us.store(0, std::memory_order_relaxed);
|
||||
queued_.store(false, std::memory_order_release);
|
||||
stop_flag_.store(true, std::memory_order_relaxed);
|
||||
fire_callbacks(closed_callbacks_);
|
||||
self_stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -623,17 +668,19 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
Obj& obj_;
|
||||
std::shared_ptr<IScheduler> scheduler_;
|
||||
std::string name_;
|
||||
std::size_t fifo_capacity_;
|
||||
input_channels_t input_channels_;
|
||||
output_channels_t output_channels_{};
|
||||
std::atomic<bool> stop_flag_{true};
|
||||
std::atomic<bool> queued_{false};
|
||||
NodeStats stats_;
|
||||
NodeErrorHandler error_handler_;
|
||||
std::chrono::milliseconds max_exec_time_{0};
|
||||
Obj& obj_;
|
||||
std::shared_ptr<IScheduler> scheduler_;
|
||||
std::string name_;
|
||||
std::size_t fifo_capacity_;
|
||||
input_channels_t input_channels_;
|
||||
output_channels_t output_channels_{};
|
||||
std::atomic<bool> stop_flag_{true};
|
||||
std::atomic<bool> queued_{false};
|
||||
NodeStats stats_;
|
||||
NodeErrorHandler error_handler_;
|
||||
std::chrono::milliseconds max_exec_time_{0};
|
||||
std::array<NodeEventCallback, 2> event_callbacks_{}; // [0]=user [1]=network
|
||||
std::array<NodeEventCallback, 2> closed_callbacks_{};
|
||||
};
|
||||
|
||||
// ── make_pool_node factory (NTTP) ─────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user