UNPKG

@x5e/gink

Version:

an eventually consistent database

65 lines (57 loc) 1.86 kB
import { flock } from "fs-ext"; import { FileHandle, open } from "fs/promises"; import { Stats } from "fs"; export class LockableFile { protected fileHandle: FileHandle; protected fileLocked: boolean = false; private lockableFileReady: Promise<void>; constructor( readonly filename: string, readonly exclusive: boolean = false, ) { this.lockableFileReady = this.initializeLockableFile(); } get ready() { return this.lockableFileReady; } private async initializeLockableFile(): Promise<void> { this.fileHandle = await open(this.filename, "a+"); if (this.exclusive) { await this.lockFile(false); } } protected async lockFile(block: boolean): Promise<boolean> { const thisLockableFile = this; return new Promise((resolve, reject) => { flock(this.fileHandle.fd, block ? "ex" : "exnb", (err) => { if (err) { return reject(err); } thisLockableFile.fileLocked = true; resolve(true); }); }); } protected async unlockFile(): Promise<void> { const thisLogBackedStore = this; return new Promise((resolve, reject) => { flock(this.fileHandle.fd, "un", async (err) => { if (err) { return reject(err); } thisLogBackedStore.fileLocked = false; resolve(); }); }); } protected async getFileLength(): Promise<number> { let stats: Stats; try { stats = await this.fileHandle.stat(); } catch (problem) { console.error(`problem with fileHandle.stat ${problem}`); throw problem; } return stats.size; } }