Cześć
Mam w express.js endpoint do komunikacji po WebSocket. Klienci używają endpoint-a do wymiany komunikatów tekstowych.
Nowe komunikaty są archiwzowane w plikach binarnych, po to żeby dołączający się klienci otrzymali x ostatnich (np 3).
Zapis i odczyt komunikatów do/z pliku jest asynchroniczny.
Jednak operacja zapisu odczytu muszą być synchroniczne, żeby nie uszkodzić spójności danych, czyli potrzebny jest jakiś rodzaj lock-a.
Tyle tytułem wstępu.
Mam taki pomysł na "locki" w node przy użyciu promise, co myślicie?
class Lock {
private locksNum:number = 0;
private promise:Promise<void>|null = null
private resolve:(()=>void)|null = null;
private makePromise() {
this.promise = new Promise(resolve => this.resolve = resolve);
}
private clearPromise() {
this.promise = null;
}
get locked():boolean {
return this.locksNum > 0;
}
get waitForRelease():Promise<void> {
if (!this.locked) throw new Error("Add lock first!");
return <Promise<void>>this.promise;
}
addLock() {
!this.locked && this.makePromise();
++this.locksNum;
}
remLock() {
if (!this.locked) throw new Error("Add lock first!");
--this.locksNum;
this.resolve && this.resolve();
this.locked ? this.makePromise() : this.clearPromise();
}
}
Niepełny kod klasy BinaryStream, tylko to co istotne.
class BinaryStream {
private _readLock:Lock = new Lock();
private _writeLock:Lock = new Lock();
public async writePacket(packet:Packet):Promise<BinaryStream> {
while (this._readLock.locked) {
await this._readLock.waitForRelease;
}
while (this._writeLock.locked) {
await this._writeLock.waitForRelease;
}
this._writeLock.addLock();
//...kod zapisujacy packet do pliku
this._writeLock.remLock();
return Promise.resolve(this);
}
public async readPacket(offset:number=0):Promise<Packet> {
while (this._writeLock.locked) {
await this._writeLock.waitForRelease;
}
this._readLock.addLock();
//...kod odczytujacy packet z pliku
this._readLock.remLock();
return Promise.resolve(packet);
}
}