Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mosquitto-dev] libmosquitto outgoing queue request for comment

Hello Greg,

As I believe you pointed out, specs are a bit vague sometimes. This makes it difficult to add functionality to the library without restricting users' imagination.

You gave a good example: "drop the oldest with the same topic". Though an obvious one, I never thought of that option (thanks for the idea). For me that just shows how different applications have different needs.

I spent some time thinking how to address the problem of limiting the queue in a flexible way without making the library too complicated. After visitng the problem many times, I finally came up with a callback. Here are some quick examples of things users could choose to do:

// limit total, drop newest
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    if (total_count > 50) return drop_new;
    return queue_msg;
}

// limit total, drop oldest
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    if (total_count > 50) return drop_oldest;
    return queue_msg;
}

// limit QoS 0 only
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    if (msg->qos == 0 && qos_count > 50) return drop_oldest;
    return queue_msg;
}

// always keep retained messages
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    if (total_count > 50 && msg->retain == false) return drop_new;
    return queue_msg;
}

// special group of topics need to be delivered
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    bool match;
    mosquitto_topic_matches_sub("special/topics/#", msg->topic, &match);
    if (match) return queue_msg;
    if (total_count > 50) return drop_oldest;
    return queue_msg;
}

// drop oldest with same topic
queue_callback_ret_t queue_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, int qos_count, int total_count) {
    if (total_count > 50) return drop_oldest_with_same_topic;
    return queue_msg;
}

By default (if you don't set a callback), the library behavior won't change. This will probably satisfy 99.9% of the users. For the 0.1% that might need more power, the price of adding a few lines does not seem that much (at least to me). Callback complexity will increase depending on particular app needs. In any case libmosquitto would remain lightweight, as it does not have to implement any logic, it only has to follow basic orders.

What you see here is just a draft, with the hope that some imaginative users in this list would suggest ways to enhance it while keeping it simple.
Regards,
Abilio


On Fri, Apr 2, 2021 at 2:31 PM Greg Troxel <gdt@xxxxxxxxxx> wrote:

My quick reaction is that this is jumping to a very complicated approach
and skipping over intermediate ones that are likely to be sufficient for
most cases.

I'm really unclear on when people decide to use qos 0/1/2 and why,
because there are dreadfully few protocol specs published (at least that
I have seen) that define the actual protocol used for communication over
MQTT.

Overall, I would lean to having queuing be optional, with configurable

  limit on # of queued messages (default 128?)

  configurable if a publish on a topic will replace the previous
  stored-and-not-yet-sent message on that same topic


Here, the big question is if there's a desire for every message to be
delivered, perhaps because it has json with a time and a value, or if
only the latest is useful, because it's just a value.   That then leads
to questions about choice of qos and persisting mesages to stable
storage so that they can survive not only broker disconnect but also
local reboot or power loss, and by the time you are done then perhaps
you should instead construct a reliable transfer protocol that uses MQTT
like UDP.

So to evaluate your proposal I'd like pointers to protocol specs of
"send this data via MQTT".  (It is both a plus and a minus of MQTT that
you can sort of get away with not defining that.)






Back to the top