Initial commit, getting all the stuff from PlatformIO
This commit is contained in:
19
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.ino
Normal file
19
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.ino
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <Arduino.h>
|
||||
#include <PicoMQTT.h>
|
||||
|
||||
PicoMQTT::Server mqtt;
|
||||
|
||||
void setup() {
|
||||
// Usual setup
|
||||
Serial.begin(115200);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin("wifiname", "password");
|
||||
while (WiFi.status() != WL_CONNECTED) { delay(1000); }
|
||||
Serial.printf("WiFi connected, IP: %s\n", WiFi.localIP().toString().c_str());
|
||||
mqtt.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// This will automatically handle client connections. By default, all clients are accepted.
|
||||
mqtt.loop();
|
||||
}
|
||||
85
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.py
Executable file
85
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.py
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import time
|
||||
import multiprocessing
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
|
||||
def consumer(barrier, conn, host, expected_messages, timeout):
|
||||
pid = multiprocessing.current_process().pid
|
||||
client = mqtt.Client(f"consumer_{pid}")
|
||||
# client.username_pw_set("username", "password")
|
||||
|
||||
total_messages = 0
|
||||
first_message_time = None
|
||||
last_message_time = None
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
nonlocal total_messages, first_message_time, last_message_time
|
||||
total_messages += 1
|
||||
last_message_time = time.time()
|
||||
first_message_time = first_message_time or last_message_time
|
||||
|
||||
def on_subscribe(client, userdata, mid, granted_qos):
|
||||
barrier.wait()
|
||||
|
||||
client.on_message = on_message
|
||||
client.on_subscribe = on_subscribe
|
||||
|
||||
client.connect(host)
|
||||
client.loop_start()
|
||||
client.subscribe("benchmark")
|
||||
while total_messages < expected_messages:
|
||||
if first_message_time and total_messages >= 2:
|
||||
elapsed_time = time.time() - first_message_time
|
||||
if elapsed_time >= timeout:
|
||||
break
|
||||
time.sleep(1)
|
||||
client.loop_stop()
|
||||
|
||||
elapsed_time = last_message_time - first_message_time
|
||||
rate = (total_messages - 1) / elapsed_time
|
||||
conn.send(rate)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("host")
|
||||
parser.add_argument("--consumers", type=int, default=1)
|
||||
parser.add_argument("--messages", type=int, default=1000)
|
||||
parser.add_argument("--size", type=int, default=1)
|
||||
parser.add_argument("--timeout", type=int, default=10)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
client = mqtt.Client("producer")
|
||||
client.connect(args.host)
|
||||
|
||||
barrier = multiprocessing.Barrier(args.consumers + 1)
|
||||
pipe = multiprocessing.Pipe(False)
|
||||
consumers = [
|
||||
multiprocessing.Process(
|
||||
target=consumer, args=(barrier, pipe[1], args.host, args.messages, args.timeout)
|
||||
)
|
||||
for _ in range(args.consumers)
|
||||
]
|
||||
|
||||
message = "0" * args.size
|
||||
|
||||
for consumer in consumers:
|
||||
consumer.start()
|
||||
|
||||
# wait for all processes to connect
|
||||
barrier.wait()
|
||||
|
||||
# fire messages
|
||||
while any(p.is_alive() for p in consumers):
|
||||
client.publish("benchmark", message)
|
||||
|
||||
# wait for consumers
|
||||
for consumer in consumers:
|
||||
consumer.join()
|
||||
|
||||
# collect results
|
||||
rate = sum(pipe[0].recv() for _ in consumers) / len(consumers)
|
||||
print(f"{rate:.1f}")
|
||||
37
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.sh
Executable file
37
.pio/libdeps/esp32dev/PicoMQTT/benchmark/benchmark.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage:
|
||||
# ./benchmark.sh <ESP IP>
|
||||
|
||||
export LC_NUMERIC=C
|
||||
|
||||
HOST="$1"
|
||||
REPEAT=5
|
||||
CONSUMER_COUNTS="12 10 5 1"
|
||||
SIZES="10000 5000 1000 500 100 50 10 5 1"
|
||||
|
||||
printf "message size\t"
|
||||
for CONSUMERS in $CONSUMER_COUNTS
|
||||
do
|
||||
printf "%i consumers\t" $CONSUMERS
|
||||
done
|
||||
printf "\n"
|
||||
|
||||
for SIZE in $SIZES
|
||||
do
|
||||
printf "%i\t" $SIZE
|
||||
for CONSUMERS in $CONSUMER_COUNTS
|
||||
do
|
||||
RESULT=$({
|
||||
for ITERATION in $(seq $REPEAT)
|
||||
do
|
||||
./benchmark.py --size=$SIZE --consumers=$CONSUMERS "$HOST"
|
||||
# potential interference may go away by itself if we wait
|
||||
sleep 1
|
||||
done
|
||||
} | awk '{ sum += $1; count += 1 } END { print sum / count }')
|
||||
|
||||
printf "%.1f\t" $RESULT
|
||||
done
|
||||
printf "\n"
|
||||
done
|
||||
24
.pio/libdeps/esp32dev/PicoMQTT/benchmark/chart.py
Executable file
24
.pio/libdeps/esp32dev/PicoMQTT/benchmark/chart.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
import csv
|
||||
import sys
|
||||
|
||||
import pygal
|
||||
|
||||
data = list(csv.DictReader(sys.stdin, dialect="excel-tab"))
|
||||
X = "message size"
|
||||
SERIES = [e for e in data[0].keys() if e and e != X]
|
||||
|
||||
chart = pygal.XY(
|
||||
legend_at_bottom=True,
|
||||
logarithmic=True,
|
||||
x_title="payload size [B]",
|
||||
y_title="messages delivery rate [1/s]",
|
||||
pretty_print=True,
|
||||
stroke_style={"width": 50},
|
||||
x_label_rotation=-90,
|
||||
)
|
||||
|
||||
for name in SERIES:
|
||||
chart.add(name, [(float(e[X]), float(e[name])) for e in data])
|
||||
|
||||
sys.stdout.write(chart.render().decode("utf-8"))
|
||||
Reference in New Issue
Block a user