1#ifndef _PAINLESS_MESH_MESSAGE_QUEUE_HPP_
2#define _PAINLESS_MESH_MESSAGE_QUEUE_HPP_
119 : maxQueueSize(maxSize), nextMessageId(1) {
131 const TSTRING& destination =
"") {
133 if (messages.size() >= maxQueueSize) {
135 if (!makeSpace(priority)) {
137 Log(
logger::ERROR,
"MessageQueue: Failed to queue message (queue full, priority too low)\n");
142 uint32_t msgId = nextMessageId++;
143 uint32_t timestamp = millis();
145 QueuedMessage msg(msgId, priority, timestamp, payload, destination);
146 messages.push_back(msg);
151 updatePriorityStats();
156 Log(
logger::GENERAL,
"MessageQueue: Enqueued message #%u (priority=%d, size=%zu/%zu)\n",
157 msgId, priority, messages.size(), (
size_t)maxQueueSize);
168 auto it = std::find_if(messages.begin(), messages.end(),
170 return msg.id == messageId;
173 if (it != messages.end()) {
177 updatePriorityStats();
181 messageId, messages.size());
201 return messages.size();
210 return std::count_if(messages.begin(), messages.end(),
212 return msg.priority == priority;
221 return messages.empty();
230 updatePriorityStats();
248 stateChangedCallback = callback;
257 auto it = std::find_if(messages.begin(), messages.end(),
259 return msg.id == messageId;
262 if (it != messages.end()) {
276 uint32_t currentTime = millis();
277 uint32_t removedCount = 0;
279 auto it = messages.begin();
280 while (it != messages.end()) {
281 if (currentTime - it->timestamp > maxAgeMs) {
282 it = messages.erase(it);
289 if (removedCount > 0) {
291 updatePriorityStats();
300 std::vector<QueuedMessage> messages;
301 uint32_t maxQueueSize = 1000;
302 uint32_t nextMessageId = 1;
323 for (
int targetPriority =
PRIORITY_LOW; targetPriority > newPriority; targetPriority--) {
324 auto it = std::find_if(messages.begin(), messages.end(),
325 [targetPriority](
const QueuedMessage& msg) {
326 return msg.priority == static_cast<MessagePriority>(targetPriority);
329 if (it != messages.end()) {
330 Log(
logger::GENERAL,
"MessageQueue: Evicting message #%u (priority=%d) to make space\n",
331 it->id, it->priority);
344 void updatePriorityStats() {
354 void checkStateChange() {
357 if (messages.empty()) {
359 }
else if (messages.size() >= maxQueueSize) {
361 }
else if (messages.size() >= maxQueueSize * 3 / 4) {
367 if (newState != currentState) {
368 currentState = newState;
369 if (stateChangedCallback) {
370 stateChangedCallback(currentState, messages.size());
Definition message_queue.hpp:112
bool empty() const
Definition message_queue.hpp:220
void clear()
Definition message_queue.hpp:227
std::vector< QueuedMessage > getMessages() const
Definition message_queue.hpp:192
void onStateChanged(queueStateChangedCallback_t callback)
Definition message_queue.hpp:247
uint32_t incrementAttempts(uint32_t messageId)
Definition message_queue.hpp:256
uint32_t size(MessagePriority priority) const
Definition message_queue.hpp:209
uint32_t size() const
Definition message_queue.hpp:200
QueueStats getStats() const
Definition message_queue.hpp:239
MessageQueue(uint32_t maxSize=1000)
Definition message_queue.hpp:118
uint32_t pruneOldMessages(uint32_t maxAgeMs)
Definition message_queue.hpp:275
uint32_t enqueue(MessagePriority priority, const TSTRING &payload, const TSTRING &destination="")
Definition message_queue.hpp:130
bool remove(uint32_t messageId)
Definition message_queue.hpp:167
String TSTRING
Definition configuration.hpp:132
painlessmesh::logger::LogClass Log
Definition wifi.cpp:2
@ GENERAL
Definition logger.hpp:26
@ ERROR
Definition logger.hpp:19
std::function< void(QueueState state, uint32_t messageCount)> queueStateChangedCallback_t
Definition message_queue.hpp:73
MessagePriority
Definition message_queue.hpp:18
@ PRIORITY_HIGH
Definition message_queue.hpp:20
@ PRIORITY_CRITICAL
Definition message_queue.hpp:19
@ PRIORITY_LOW
Definition message_queue.hpp:22
@ PRIORITY_NORMAL
Definition message_queue.hpp:21
QueueState
Definition message_queue.hpp:28
@ QUEUE_EMPTY
Definition message_queue.hpp:29
@ QUEUE_NORMAL
Definition message_queue.hpp:30
@ QUEUE_75_PERCENT
Definition message_queue.hpp:31
@ QUEUE_FULL
Definition message_queue.hpp:32
Definition message_queue.hpp:58
uint32_t lowQueued
Definition message_queue.hpp:69
uint32_t totalSent
Definition message_queue.hpp:60
uint32_t totalQueued
Definition message_queue.hpp:59
uint32_t totalDropped
Definition message_queue.hpp:61
uint32_t currentSize
Definition message_queue.hpp:62
uint32_t highQueued
Definition message_queue.hpp:67
uint32_t criticalQueued
Definition message_queue.hpp:66
uint32_t maxSize
Definition message_queue.hpp:63
uint32_t normalQueued
Definition message_queue.hpp:68
Definition message_queue.hpp:39
QueuedMessage(uint32_t msgId, MessagePriority prio, uint32_t ts, const TSTRING &data, const TSTRING &dest="")
Definition message_queue.hpp:49
TSTRING payload
Definition message_queue.hpp:44
MessagePriority priority
Definition message_queue.hpp:41
QueuedMessage()
Definition message_queue.hpp:47
uint32_t attempts
Definition message_queue.hpp:43
uint32_t timestamp
Definition message_queue.hpp:42
TSTRING destination
Definition message_queue.hpp:45
uint32_t id
Definition message_queue.hpp:40
painlessmesh::logger::LogClass Log
Definition wifi.cpp:2