comparison util/smqueue.lua @ 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 8baaefc4db79
children 21126415c8a0
comparison
equal deleted inserted replaced
14000:071779f7645c 14001:df970d2dac45
30 local v = self._queue:pop(); 30 local v = self._queue:pop();
31 if not v then return nil, "pop" end 31 if not v then return nil, "pop" end
32 table.insert(acked, v); 32 table.insert(acked, v);
33 end 33 end
34 34
35 local c = self._next_checkpoint;
36 if c and h >= c then
37 self:_call_checkpoints(h);
38 end
39
35 return acked 40 return acked
36 end 41 end
37 42
38 function smqueue:count_unacked() return self._head - self._tail end 43 function smqueue:count_unacked() return self._head - self._tail end
39 44
49 local t = {}; 54 local t = {};
50 for i, v in self:resume() do t[i] = v; end 55 for i, v in self:resume() do t[i] = v; end
51 return t 56 return t
52 end 57 end
53 58
59 -- Add a 'checkpoint' which will call a function when all the stanzas
60 -- currently in the queue have been successfully delivered and acknowledged
61 function smqueue:add_checkpoint(cb, ud)
62 table.insert(self._checkpoints, { self._head, cb, ud });
63 if not self._next_checkpoint then
64 self._next_checkpoint = self._head;
65 end
66 end
67 };
68
69 function smqueue:_call_checkpoints(h)
70 local checkpoints = self._checkpoints;
71
72 -- Pop the checkpoint info and update the next checkpoint info
73 local c = table.remove(checkpoints, 1);
74 self._next_checkpoint = checkpoints[1] and checkpoints[1][1] or nil;
75
76 -- Call the callback
77 local cb, ud = c[2], c[3];
78 cb(ud);
79
80 -- In case we passed over multiple checkpoints, call them also
81 if h >= self._next_checkpoint then
82 return self:_call_checkpoints(h);
83 end
84 end
85
54 local smqueue_mt = { 86 local smqueue_mt = {
55 __name = "smqueue"; 87 __name = "smqueue";
56 __index = smqueue; 88 __index = smqueue;
57 __len = smqueue.count_unacked; 89 __len = smqueue.count_unacked;
58 -- Return a simple object for serialization 90 -- Return a simple object for serialization
65 assert(size > 0); 97 assert(size > 0);
66 return setmetatable({ 98 return setmetatable({
67 _head = 0; 99 _head = 0;
68 _tail = 0; 100 _tail = 0;
69 _queue = queue.new(size, true); 101 _queue = queue.new(size, true);
102 _checkpoints = {};
70 }, smqueue_mt) 103 }, smqueue_mt)
71 end 104 end
72 105
73 return lib 106 return lib