fix: implement write-lock for agent cache
This commit is contained in:
parent
5569ba4660
commit
eb922c9318
@ -159,7 +159,7 @@ export default function MachineRow({ machine, routes, magic, users, stats }: Pro
|
|||||||
<p className="font-semibold leading-snug">
|
<p className="font-semibold leading-snug">
|
||||||
{hinfo.getTSVersion(stats)}
|
{hinfo.getTSVersion(stats)}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-300">
|
<p className="text-sm text-gray-500 dark:text-gray-300 max-w-48 truncate">
|
||||||
{hinfo.getOSInfo(stats)}
|
{hinfo.getOSInfo(stats)}
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { HostInfo } from '~/utils/types';
|
import type { HostInfo } from '~/types';
|
||||||
|
|
||||||
export function getTSVersion(host: HostInfo) {
|
export function getTSVersion(host: HostInfo) {
|
||||||
const { IPNVersion } = host;
|
const { IPNVersion } = host;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { setTimeout as pSetTimeout } from 'node:timers/promises';
|
|||||||
import type { LoaderFunctionArgs } from 'react-router';
|
import type { LoaderFunctionArgs } from 'react-router';
|
||||||
import type { HostInfo } from '~/types';
|
import type { HostInfo } from '~/types';
|
||||||
import { WebSocket } from 'ws';
|
import { WebSocket } from 'ws';
|
||||||
import { log } from './log';
|
import log from './log';
|
||||||
|
|
||||||
// Essentially a HashMap which invalidates entries after a certain time.
|
// Essentially a HashMap which invalidates entries after a certain time.
|
||||||
// It also is capable of syncing as a compressed file to disk.
|
// It also is capable of syncing as a compressed file to disk.
|
||||||
@ -13,6 +13,7 @@ class TimedCache<K, V> {
|
|||||||
private _timeCache = new Map<K, number>();
|
private _timeCache = new Map<K, number>();
|
||||||
private defaultTTL: number;
|
private defaultTTL: number;
|
||||||
private filepath: string;
|
private filepath: string;
|
||||||
|
private writeLock = false;
|
||||||
|
|
||||||
constructor(defaultTTL: number, filepath: string) {
|
constructor(defaultTTL: number, filepath: string) {
|
||||||
this.defaultTTL = defaultTTL;
|
this.defaultTTL = defaultTTL;
|
||||||
@ -51,21 +52,28 @@ class TimedCache<K, V> {
|
|||||||
this._timeCache.set(key, expires);
|
this._timeCache.set(key, expires);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e['code'] !== 'ENOENT') {
|
if (e.code === 'ENOENT') {
|
||||||
// log.error('CACH', 'Failed to load cache from file', e);
|
log.debug('CACH', 'Cache file not found, creating new cache');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// log.debug('CACH', 'Cache file not found, creating new cache');
|
log.error('CACH', 'Failed to load cache from file', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async syncToFile() {
|
private async syncToFile() {
|
||||||
|
while (this.writeLock) {
|
||||||
|
await pSetTimeout(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.writeLock = true;
|
||||||
const data = Array.from(this._cache.entries()).map(([key, value]) => {
|
const data = Array.from(this._cache.entries()).map(([key, value]) => {
|
||||||
return { key, value, expires: this._timeCache.get(key) }
|
return { key, value, expires: this._timeCache.get(key) }
|
||||||
});
|
});
|
||||||
|
|
||||||
await writeFile(this.filepath, JSON.stringify(data), 'utf-8');
|
await writeFile(this.filepath, JSON.stringify(data), 'utf-8');
|
||||||
|
await this.loadFromFile();
|
||||||
|
this.writeLock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +100,7 @@ export async function queryAgent(nodes: string[]) {
|
|||||||
|
|
||||||
const cached: Record<string, HostInfo> = {};
|
const cached: Record<string, HostInfo> = {};
|
||||||
await Promise.all(nodes.map(async node => {
|
await Promise.all(nodes.map(async node => {
|
||||||
const cachedData = await cache.get(node);
|
const cachedData = await cache?.get(node);
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
cached[node] = cachedData;
|
cached[node] = cachedData;
|
||||||
}
|
}
|
||||||
@ -114,17 +122,17 @@ export async function queryAgent(nodes: string[]) {
|
|||||||
agentSocket.send(JSON.stringify({ NodeIDs: uncached }));
|
agentSocket.send(JSON.stringify({ NodeIDs: uncached }));
|
||||||
const returnData = await new Promise<Record<string, HostInfo> | void>((resolve, reject) => {
|
const returnData = await new Promise<Record<string, HostInfo> | void>((resolve, reject) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
agentSocket.removeAllListeners('message');
|
agentSocket?.removeAllListeners('message');
|
||||||
resolve();
|
resolve();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
agentSocket.on('message', async (message: string) => {
|
agentSocket?.on('message', async (message: string) => {
|
||||||
const data = JSON.parse(message.toString());
|
const data = JSON.parse(message.toString());
|
||||||
if (Object.keys(data).length === 0) {
|
if (Object.keys(data).length === 0) {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
agentSocket.removeAllListeners('message');
|
agentSocket?.removeAllListeners('message');
|
||||||
resolve(data);
|
resolve(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user