Skip to content

Commit effe3f6

Browse files
committed
Use mutex in persistent storage
1 parent 89bbc5f commit effe3f6

5 files changed

Lines changed: 33 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to homebridge-dummy will be documented in this file.
44

5-
## 1.5.16-beta.0 ()
5+
## 1.5.16-beta.1 ()
66

77
### Added
88
- Added `topicGetAvailable` for "Last Will and Testament" (LWT) before an accessory goes offline
@@ -11,6 +11,9 @@ All notable changes to homebridge-dummy will be documented in this file.
1111
### Changed
1212
- Renamed "Get Availability" to "Get Active Status" in config UI to avoid confusion with the new `topicGetAvailable` (see above)
1313

14+
### Fixed
15+
- Potential race condition in persistent storage
16+
1417
## 1.5.15 (2026-05-12)
1518

1619
### Fixed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"displayName": "Homebridge Easy MQTT",
55
"description": "Homebridge plugin for MQTT devices",
66
"type": "module",
7-
"version": "1.5.16-beta.0",
7+
"version": "1.5.16-beta.1",
88
"homepage": "https://github.com/mpatfield/homebridge-easy-mqtt#readme",
99
"repository": {
1010
"type": "git",

src/tools/mutex.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export class Mutex {
2+
3+
private _lock: Promise<void> = Promise.resolve();
4+
5+
public async lock<T>(fn: () => T | Promise<T>): Promise<T> {
6+
const prev = this._lock;
7+
let release!: () => void;
8+
this._lock = new Promise(r => release = r);
9+
await prev;
10+
try {
11+
return await fn();
12+
} finally {
13+
release();
14+
}
15+
}
16+
}

src/tools/properties.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { PrimitiveTypes } from 'homebridge';
22
import storage from 'node-persist';
33

4+
import { Mutex } from './mutex.js';
5+
46
import { PLATFORM_NAME } from '../homebridge/settings.js';
57

68
type Storable = PrimitiveTypes | PrimitiveTypes[] | { [key: string]: PrimitiveTypes };
79
const PROPERTIES = new Map<string, Map<string, Storable>>();
810

11+
const MUTEX = new Mutex();
12+
913
export class Properties {
1014

1115
public static async initStorage(persistPath: string) {
@@ -66,6 +70,12 @@ export class Properties {
6670
}
6771

6872
private static async save() {
73+
await MUTEX.lock(async () => {
74+
await Properties._save();
75+
});
76+
}
77+
78+
private static async _save() {
6979
const storageArray = Array.from(PROPERTIES.entries()).map(([key, value]) => {
7080
return [key, Array.from(value.entries())];
7181
});

0 commit comments

Comments
 (0)