Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

How can I implement offline publishing queue in mJS?

I have a data packet (JSON string) which I send every minute to the cloud. Incase there is no internet available, I want to store this value in a queue to later publish when the MCU receives internet. I dont see a queue data structure available in mJS. What is the correct method to implement this if I am coding in mJS on mongoose os. Also, is the "offline publishing queue" feature of AWS IOT SDK implemented in Mongoose OS?

Thanks

Comments

  • mamuespmamuesp Germany/Northern coast
    edited August 5

    I implemented it like this (no warranty at all!):

    let protQueue = {
        _queue: [],
        isEmpty: function() {
            return (this._queue.length === 0);
        },
        add: function(obj) {
            this._queue.push(obj);
        },
        count: function() {
            return this._queue.length;
        },
        first: function(remove) {
            if (this.isEmpty()) {
                return {};
            } else {
                let elem = this._queue[0];
                if (remove) {
                    this._queue.splice(0, 1);
                }
                return elem;
            }
        },
        last: function(remove) {
            if (this.isEmpty()) {
                return {};
            } else {
                let elem = this._queue[this._queue.length - 1];
                if (remove) {
                    this._queue.splice(this._queue.length - 1, 1);
                }
                return elem;
            }
        },
        print: function() {
            for (let i = 0; i < this._queue.length; i++) {
                let msg = 'Queue entry - JSON: ' + JSON.stringify(this._queue[i]);
                Log.debug(msg);
            }
        },
        get: function() {
            return this._queue;
        },
        set: function(value) {
            this._queue = value;
        }
    };
    

    and you may use it as a kind of "prototype" (see MJS documentation):

    let queue = Object.create(protQueue);
    

    and the call the functions of the object.

    Remark: "get" and "set" are returning or setting the whole array handled as queue.

    So if there is no connection, the topic and payload are stored in the queue (as object, like {topic: "my topic", payload: "my payload"}) and when there's a connection again, the queue will be published (hence the parameter removewhen calling firstor last, so you may get the last entry and remove it also from the queue, then publish it via MQTT.

  • Thanks. This works. Very useful and concise code snippet.
    Small issue - i got the error - MJS callback error: [Log] is not defined on the log.debug stage. I converted it to a print command and it works. Any thoughts on how to fix this error.

    Another Quick doubt - is it possible that while i am trying to remove an element from the queue, an interrupt occurs elsewhere in the code, and another code block is executed which is inserting into the queue. Can this lead to the queue going corrupt? Does Mongoose OS take care of these concurrency issues, or will this have to be handled by me?

    Thanks again for the help.

  • mamuespmamuesp Germany/Northern coast
    edited August 5

    Sorry, forgot this: add load("api_log.js");to the code. But these are basic functions, it is very recommended to get to know them.

    AFAIK interrupts won't break MJS calls. They are queued, for the moment only the last one, but we discussed with @rojer that would it be helpful to have some more interrupts queued. Because in the current MJS implementation you will lose interrupts if they come to fast. So if you need to be sure to catch them, you will need to go to the Carea and write an interrupt handler even running in the ISR context.

  • Thanks. This is very helpful.

Sign In or Register to comment.