changeset 14001:df970d2dac45

util.smqueue: Add "checkpoints" API to run code on successful stanza delivery
author Matthew Wild <mwild1@gmail.com>
date Sat, 06 Dec 2025 15:57:36 +0000
parents 071779f7645c
children f82be93b61a5
files util/smqueue.lua
diffstat 1 files changed, 33 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/util/smqueue.lua	Fri Dec 05 17:53:52 2025 +0100
+++ b/util/smqueue.lua	Sat Dec 06 15:57:36 2025 +0000
@@ -32,6 +32,11 @@
 		table.insert(acked, v);
 	end
 
+	local c = self._next_checkpoint;
+	if c and h >= c then
+		self:_call_checkpoints(h);
+	end
+
 	return acked
 end
 
@@ -51,6 +56,33 @@
 	return t
 end
 
+-- Add a 'checkpoint' which will call a function when all the stanzas
+-- currently in the queue have been successfully delivered and acknowledged
+function smqueue:add_checkpoint(cb, ud)
+	table.insert(self._checkpoints, { self._head, cb, ud });
+	if not self._next_checkpoint then
+		self._next_checkpoint = self._head;
+	end
+end
+};
+
+function smqueue:_call_checkpoints(h)
+	local checkpoints = self._checkpoints;
+
+	-- Pop the checkpoint info and update the next checkpoint info
+	local c = table.remove(checkpoints, 1);
+	self._next_checkpoint = checkpoints[1] and checkpoints[1][1] or nil;
+
+	-- Call the callback
+	local cb, ud = c[2], c[3];
+	cb(ud);
+
+	-- In case we passed over multiple checkpoints, call them also
+	if h >= self._next_checkpoint then
+		return self:_call_checkpoints(h);
+	end
+end
+
 local smqueue_mt = {
 	__name = "smqueue";
 	__index = smqueue;
@@ -67,6 +99,7 @@
 		_head = 0;
 		_tail = 0;
 		_queue = queue.new(size, true);
+		_checkpoints = {};
 	}, smqueue_mt)
 end