Closed Flavien closed 1 month ago
Doesn't this have a bug, or am I misreading it @Koenkk / @mikekap ?
public async execute<T>(func: () => Promise<T>, key: string | number = null): Promise<T> {
const job : Job = {key, running: false, start: null};
// Minor optimization/workaround: various tests like the idea that a job that is
// immediately runnable is run without an event loop spin. This also helps with stack
// traces in some cases, so avoid an `await` if we can help it.
this.jobs.push(job);
if (this.getNext() !== job) {
await new Promise((resolve): void => {
job.start = (): void => {
job.running = true;
resolve(null);
};
this.executeNext();
});
} else {
job.running = true;
}
try {
return await func();
} finally {
this.jobs.splice(this.jobs.indexOf(job), 1);
this.executeNext();
}
}
The first job to come in will be set as running = true
, and gets suspended at await func()
. Then assuming it doesn't finish running before the next message is received through MQTT, this function will re-enter with the new job, which gets added to this.jobs
, getNext()
returns null
so job.running
is set to true
, and await func()
is executed, even though the first job hasn't finished yet?
If getNext()
returns null
, getNext() !== job
will be true - so we await the promise to get a slot on the queue. The else clause doesn't get taken the second time.
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days
What happened?
The Zigbee messages are sent by Z2M out of order from the order they are consumed from MQTT.
What did you expect to happen?
See detailed logs below, the Zigbee messages should be sent in the same order as they are received from the MQTT broker. As you can see below, the messages got consumed in order
1
,2
,3
,4
but the Zigbee messages were sent in order1
,3
,4
,2
.Ideally, the order should be preserved:
2
is sent before3
.2
all together, and we don't send it after3
and4
have already been sent.How to reproduce it (minimal and precise)
Here is an extract of my Zigbee2MQTT logs:
Lines
1 - 4
, we send a{"scene_recall":1}
message to the group, the scene recall is correctly applied.Line
5 - 6
is where the issue is triggered. We send a{"scene_recall":2}
message, which is received and processed by Zigbee2MQTT as evidenced by this log entry, however the Zigbee message is not immediately sent.Line
7 - 10
, before Z2M has the time to send the Zigbee message for scene 2, we quickly send another MQTT message with{"scene_recall":1}
to the group. As you can see on line 9 and 10, the scene is successfully recalled (the scene is visibly applied to the light).Line
11 - 13
, we send{"state":"OFF"}
, and at that point the light correctly turns off.The anomaly shows up on line
14 -15
: the scene recall from lines5 - 6
is now being sent (late), and the light turns back on.Note this all happens very quickly (in the span of 3 seconds).
Zigbee2MQTT version
1.35.1
Adapter firmware version
20221226
Adapter
SONOFF Zigbee 3.0 USB Dongle Plus-P
Setup
Z2M on Docker on Raspberry Pi 4
Debug log
No response