feat: save/restore database snapshots (#78)
This commit is contained in:
parent
e9c71c1d71
commit
ada876dec7
|
@ -41,9 +41,8 @@ class Database {
|
|||
}
|
||||
|
||||
databaseInitialize(cb) {
|
||||
// TODO: save in the db results by using a combination of concatMap and scan, to save results in batches
|
||||
fromEvent(this.events, "updateDB").subscribe(({eventKey, eventData}) => {
|
||||
if (eventData.removed) {
|
||||
if (eventData.removed) {
|
||||
this.deleteEvent(eventKey, eventData.id);
|
||||
return;
|
||||
}
|
||||
|
@ -56,6 +55,25 @@ class Database {
|
|||
});
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this.db.serialize();
|
||||
}
|
||||
|
||||
restore(serializedDb, forced) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const collections = this.db.listCollections();
|
||||
if (!collections?.length || forced) {
|
||||
this.db.loadJSON(serializedDb);
|
||||
this.db.saveDatabase(err => {
|
||||
if(err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getLastKnownEvent(eventKey) {
|
||||
const collection = this.db.getCollection(eventKey);
|
||||
if (collection?.count()) {
|
||||
|
@ -99,9 +117,10 @@ class Database {
|
|||
deleteEvent(eventKey, eventId) {
|
||||
const collection = this.db.getCollection(eventKey);
|
||||
if (collection)
|
||||
collection.chain()
|
||||
.find({id: eventId})
|
||||
.remove();
|
||||
collection
|
||||
.chain()
|
||||
.find({id: eventId})
|
||||
.remove();
|
||||
}
|
||||
|
||||
deleteNewestBlocks(eventKey, gteBlockNum) {
|
||||
|
@ -109,9 +128,10 @@ class Database {
|
|||
|
||||
const collection = this.db.getCollection(eventKey);
|
||||
if (collection)
|
||||
collection.chain()
|
||||
.find({blockNumber: {$gte: gteBlockNum}})
|
||||
.remove();
|
||||
collection
|
||||
.chain()
|
||||
.find({blockNumber: {$gte: gteBlockNum}})
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ export default class Subspace {
|
|||
this.options.callInterval = options.callInterval;
|
||||
this.options.dbFilename = options.dbFilename ?? "subspace.db";
|
||||
this.options.disableDatabase = options.disableDatabase;
|
||||
this.options.snapshot = options.snapshot;
|
||||
|
||||
this.networkId = undefined;
|
||||
this.isWebsocketProvider = options.disableSubscriptions ? false : !!web3?.currentProvider?.on;
|
||||
|
@ -44,6 +45,11 @@ export default class Subspace {
|
|||
} else {
|
||||
this._db = new Database(this.options.dbFilename, this.events);
|
||||
}
|
||||
|
||||
if(this.options.snapshot) {
|
||||
await this._db.restore(this.options.snapshot);
|
||||
}
|
||||
|
||||
this.eventSyncer = new EventSyncer(this.web3.eth, this.events, this._db, this.isWebsocketProvider);
|
||||
this.logSyncer = new LogSyncer(this.web3.eth, this.events, this._db);
|
||||
|
||||
|
@ -308,4 +314,12 @@ export default class Subspace {
|
|||
close() {
|
||||
this.eventSyncer.close();
|
||||
}
|
||||
|
||||
snapshot() {
|
||||
return this._db.serialize();
|
||||
}
|
||||
|
||||
async loadSnapshot(serializedDb) {
|
||||
return this._db.restore(serializedDb, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ export default class Subspace {
|
|||
trackGasPrice(): Observable<string>;
|
||||
trackAverageBlocktime(): Observable<number>;
|
||||
close(): void;
|
||||
snapshot(): string;
|
||||
async loadSnapshot(serializedDb: string): void;
|
||||
}
|
||||
|
||||
export interface ContractLike {
|
||||
|
|
Loading…
Reference in New Issue