From d9e0b6870201d9200b3c225903b43b850475600b Mon Sep 17 00:00:00 2001 From: eunhhu Date: Wed, 30 Sep 2026 03:32:07 +0100 Subject: Hold a window of each output's sends in its transport, not the outbox A link's ring and a wire's queue took every saved send of their output and kept it until delivered: with the receiver down they held the outbox a second time, 178 B and 313 B more a send (104). Each outlet now holds a window, --window bytes (4 MiB) and 65,536 sends past what its receiver has, at least one; the outbox keeps the rest. The owner remembers each outlet's place in the outbox and looks on from there after a save and after its transports deliver. Places move back by the sends that left the outbox since (PureApp.sends_gone), so a trim before a place skips nothing, and sends queued before are not looked at again however many wait. pure_app_sent reads a send by its place (the newest-first visit it replaces is gone); pure_link_held and pure_wire_held say what a transport holds. With the receiver down a node now grows by the outbox alone once the window is full: 219 and 218 B a send over the link and HTTP (399 and 534 B before). check.py server_windows keeps the receivers of a sender's two outputs, one linked and one over HTTP, down through 300 buys with a 2,000-byte window, then starts them: each applies all 300 once. Without the refill after deliveries the link stops at 117. --- core/module.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'core/module.c') diff --git a/core/module.c b/core/module.c index ac46fb3..b370f4b 100644 --- a/core/module.c +++ b/core/module.c @@ -2711,6 +2711,7 @@ static PureResult let_sends_go(PureApp *app, uint32_t output, uint64_t through) PureResult removed = pure_list_remove(app->outbox, i, &app->undo); if (removed != PURE_OK) return removed; --app->sent_saved; + ++app->sends_gone; app->links_changed = true; } return PURE_OK; @@ -2957,7 +2958,7 @@ PureResult pure_app_message_fields(PureApp *app, uint32_t input, const char *key } /* The outbox's item at: its output (the module's, by name), number and payload. */ -static bool sent_at(const PureApp *app, size_t at, uint32_t *output, uint64_t *seq, PureSpan *payload) { +bool pure_app_sent(const PureApp *app, size_t at, uint32_t *output, uint64_t *seq, PureSpan *payload) { PureCell name = pure_list_get(app->outbox, at, 0), bytes = pure_list_get(app->outbox, at, 2); const PureModule *m = app->module; uint32_t i = 0; @@ -2973,16 +2974,7 @@ void pure_app_outbox(const PureApp *app, PureSentVisit visit, void *context) { uint32_t output; uint64_t seq; PureSpan payload; - if (sent_at(app, i, &output, &seq, &payload) && !visit(context, output, seq, payload)) return; - } -} - -void pure_app_outbox_newest(const PureApp *app, PureSentVisit visit, void *context) { - for (size_t i = app->sent_saved; i-- > 0;) { - uint32_t output; - uint64_t seq; - PureSpan payload; - if (sent_at(app, i, &output, &seq, &payload) && !visit(context, output, seq, payload)) return; + if (pure_app_sent(app, i, &output, &seq, &payload) && !visit(context, output, seq, payload)) return; } } -- cgit v1.2.3