This PR improved receiving NOW messages throughput. And added some additional stats about buffers state. OLED screen hows now buffers states as 2 progressbar lines at the bottom of the screen.
NOW node that sends and receives NOW messages have 2 buffers:
volatile buffer for 20 NOW messages regardless of message length, this is only for receiving messages
non-volatile buffer of 20kb that can hold 74-1176 messages, depending on message payload side that can be up to 250 bytes, this buffer contains also outgoing messages and success/failure responses. (for this test, there were no outgoing messages)
On incoming NOW message, message is stored to volatile buffer, if there is no free slots for message, then it's discarded.
NOW node has first priority to free volatile buffer by moving incoming message to non-volatile buffer. If there is no free space in non-volatile buffer, then message is kept in volatile buffer until space is freed from non-volatile buffer.
Now node frees non-volatile buffer by sending incoming messages over serial to be published in MQTT.
Incoming message test
Made simple test that would send NOW messages with payload about 27 characters long to NOW gateway for about 30 seconds with 50 milliseconds interval, then pause for 60 seconds (allowing to free all buffers) and start new test circle with about 20% reduced interval. Additionally made test with 100ms interval.
This test is meant to how much messages NOW gateway can receive until it's buffer gets filled and starts dropping messages. Sent messages was received with simple node.js app over MQTT that checked messages sequence number and if detected dropped message, then stopped test. All messages were received in same order as sent out.
Message interval
Messages received until first dropped message
About time since first message to first dropped message
100ms
~3700
6m10s
50ms
816
41s
40ms
707
28s
32ms
638
20s
25ms
588
15s
20ms
557
11s
16ms
542
9s
12ms
525
6s
9ms
515
5s
7ms
246
2s
5ms
42
0.2s
Based on test message length, non-volatile buffer should be able to hold about 250 test messages. Two last test results indicates that first message that was dropped was because of volatile buffer was not emptied to non-volatile buffer fast enough although there was free space for messages in non-volatile buffer. For other tests, first message was dropped when non-volatile buffer and volatile buffer got full.
Sending messages every 110ms kept buffers empty all the time, this mean for my test I can constantly send about 9.9 messages per seconds for long duration, if sending 10 messages per second, then it took over 6 minutes until buffers got filled.
Volatile buffer with space for 20 messages means that NOW gateway can receive 20 messages at one time without delay between messages, then it needs some time to move messages to non-volatile buffer and is ready to accept new messages.
Moving 20 messages from volatile buffer to non-volatile buffer takes about 0.5 seconds.
Moving full non-volatile buffer over serial about 50 seconds.
Software serial between ESP8266 nodes runs at 9600 bits/second without any data corruption, increasing speed to 19200 bits/second introduces some data corruption. At the moment I think performance is good, maybe introduce additional software serial connections between ESP-s to increase overall throughput.
EDIT
Made additional test with 250 byte payload, then I could send constantly messages with 80ms interval or 12.5 messages per seconds without filling buffers. Also freeing all full buffers took about 7 seconds instead of 50 seconds. Did not expect better performance, so this topic need more investigation.
Ok, JSON serialization was done twice, removed that and allocation less memory for creating JSON object. Now i'm getting same message throughput (80ms interval or 12.5 messages per seconds) with 250 bytes messages and 1 byte messages. I think JSON serialization takes lot of time.
This PR improved receiving NOW messages throughput. And added some additional stats about buffers state. OLED screen hows now buffers states as 2 progressbar lines at the bottom of the screen.
NOW node that sends and receives NOW messages have 2 buffers:
On incoming NOW message, message is stored to volatile buffer, if there is no free slots for message, then it's discarded.
NOW node has first priority to free volatile buffer by moving incoming message to non-volatile buffer. If there is no free space in non-volatile buffer, then message is kept in volatile buffer until space is freed from non-volatile buffer.
Now node frees non-volatile buffer by sending incoming messages over serial to be published in MQTT.
Incoming message test
Made simple test that would send NOW messages with payload about 27 characters long to NOW gateway for about 30 seconds with 50 milliseconds interval, then pause for 60 seconds (allowing to free all buffers) and start new test circle with about 20% reduced interval. Additionally made test with 100ms interval.
This test is meant to how much messages NOW gateway can receive until it's buffer gets filled and starts dropping messages. Sent messages was received with simple node.js app over MQTT that checked messages sequence number and if detected dropped message, then stopped test. All messages were received in same order as sent out.
Based on test message length, non-volatile buffer should be able to hold about 250 test messages. Two last test results indicates that first message that was dropped was because of volatile buffer was not emptied to non-volatile buffer fast enough although there was free space for messages in non-volatile buffer. For other tests, first message was dropped when non-volatile buffer and volatile buffer got full.
Sending messages every 110ms kept buffers empty all the time, this mean for my test I can constantly send about 9.9 messages per seconds for long duration, if sending 10 messages per second, then it took over 6 minutes until buffers got filled.
Volatile buffer with space for 20 messages means that NOW gateway can receive 20 messages at one time without delay between messages, then it needs some time to move messages to non-volatile buffer and is ready to accept new messages.
Moving 20 messages from volatile buffer to non-volatile buffer takes about 0.5 seconds.
Moving full non-volatile buffer over serial about 50 seconds.
Software serial between ESP8266 nodes runs at 9600 bits/second without any data corruption, increasing speed to 19200 bits/second introduces some data corruption. At the moment I think performance is good, maybe introduce additional software serial connections between ESP-s to increase overall throughput.
EDIT
Made additional test with 250 byte payload, then I could send constantly messages with 80ms interval or 12.5 messages per seconds without filling buffers. Also freeing all full buffers took about 7 seconds instead of 50 seconds. Did not expect better performance, so this topic need more investigation. Ok, JSON serialization was done twice, removed that and allocation less memory for creating JSON object. Now i'm getting same message throughput (80ms interval or 12.5 messages per seconds) with 250 bytes messages and 1 byte messages. I think JSON serialization takes lot of time.