delay writing disk cache until block handler completes
This commit is contained in:
parent
2773bbfd00
commit
bb1ee90b0b
@ -520,6 +520,8 @@ class Blocks {
|
||||
}
|
||||
|
||||
public async $updateBlocks() {
|
||||
diskCache.lock();
|
||||
|
||||
let fastForwarded = false;
|
||||
const blockHeightTip = await bitcoinApi.$getBlockHeightTip();
|
||||
|
||||
@ -658,6 +660,8 @@ class Blocks {
|
||||
// wait for pending async callbacks to finish
|
||||
await Promise.all(callbackPromises);
|
||||
}
|
||||
|
||||
diskCache.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,11 @@ class DiskCache {
|
||||
private static CHUNK_FILES = 25;
|
||||
private isWritingCache = false;
|
||||
|
||||
private semaphore: { resume: (() => void)[], locks: number } = {
|
||||
resume: [],
|
||||
locks: 0,
|
||||
};
|
||||
|
||||
constructor() {
|
||||
if (!cluster.isPrimary) {
|
||||
return;
|
||||
@ -73,6 +78,7 @@ class DiskCache {
|
||||
fs.renameSync(DiskCache.TMP_FILE_NAMES.replace('{number}', i.toString()), DiskCache.FILE_NAMES.replace('{number}', i.toString()));
|
||||
}
|
||||
} else {
|
||||
await this.$yield();
|
||||
await fsPromises.writeFile(DiskCache.TMP_FILE_NAME, JSON.stringify({
|
||||
network: config.MEMPOOL.NETWORK,
|
||||
cacheSchemaVersion: this.cacheSchemaVersion,
|
||||
@ -82,6 +88,7 @@ class DiskCache {
|
||||
mempoolArray: mempoolArray.splice(0, chunkSize),
|
||||
}), { flag: 'w' });
|
||||
for (let i = 1; i < DiskCache.CHUNK_FILES; i++) {
|
||||
await this.$yield();
|
||||
await fsPromises.writeFile(DiskCache.TMP_FILE_NAMES.replace('{number}', i.toString()), JSON.stringify({
|
||||
mempool: {},
|
||||
mempoolArray: mempoolArray.splice(0, chunkSize),
|
||||
@ -175,6 +182,32 @@ class DiskCache {
|
||||
logger.warn('Failed to parse mempoool and blocks cache. Skipping. Reason: ' + (e instanceof Error ? e.message : e));
|
||||
}
|
||||
}
|
||||
|
||||
private $yield(): Promise<void> {
|
||||
if (this.semaphore.locks) {
|
||||
logger.debug('Pause writing mempool and blocks data to disk cache (async)');
|
||||
return new Promise((resolve) => {
|
||||
this.semaphore.resume.push(resolve);
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
public lock(): void {
|
||||
this.semaphore.locks++;
|
||||
}
|
||||
|
||||
public unlock(): void {
|
||||
this.semaphore.locks = Math.max(0, this.semaphore.locks - 1);
|
||||
if (!this.semaphore.locks && this.semaphore.resume.length) {
|
||||
const nextResume = this.semaphore.resume.shift();
|
||||
if (nextResume) {
|
||||
logger.debug('Resume writing mempool and blocks data to disk cache (async)');
|
||||
nextResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new DiskCache();
|
||||
|
@ -206,6 +206,8 @@ class Server {
|
||||
setTimeout(this.runMainUpdateLoop.bind(this), 1000 * this.currentBackendRetryInterval);
|
||||
this.currentBackendRetryInterval *= 2;
|
||||
this.currentBackendRetryInterval = Math.min(this.currentBackendRetryInterval, 60);
|
||||
} finally {
|
||||
diskCache.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user