realm-object-server
Version:
91 lines • 4.27 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const realms_1 = require("../realms");
const moment = require("moment");
const util_1 = require("./util");
class RealmHoover {
constructor({ intervalSeconds, realmFactory, logger, getSyncClient }) {
this.timer = setInterval(() => this.runVacuum(), intervalSeconds * 1000);
this.adminRealmPromise = realmFactory.open(realms_1.AdminRealm);
this.logger = logger;
this.interval = intervalSeconds;
this.getSyncClient = getSyncClient;
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
if (this.timer) {
clearInterval(this.timer);
delete this.timer;
}
if (this.adminRealmPromise) {
const realm = yield util_1.getValueIfResolved(this.adminRealmPromise);
if (realm) {
realm.close();
}
delete this.adminRealmPromise;
}
delete this.getSyncClient;
});
}
runVacuum() {
return __awaiter(this, void 0, void 0, function* () {
let realmFile;
try {
const realm = yield this.adminRealmPromise;
yield util_1.downloadAllServerChanges(realm);
const targetDate = moment().subtract(1, "day").toDate();
const files = realm.objects("RealmFile")
.filtered("lastVacuumed = NULL || lastVacuumed < $0", targetDate);
if (!this.shouldRun(files)) {
return;
}
realmFile = this.getRealmToVacuum(files);
if (!realmFile) {
return;
}
realm.write(() => {
realmFile.lastVacuumed = new Date();
});
const client = this.getSyncClient(["role=master", `label=${realmFile.syncLabel}`]);
yield client.compactRealm(realmFile.path);
}
catch (err) {
const message = `An error occurred while trying to vacuum${realmFile ? ` '${realmFile.path}'` : ""}`;
this.logger.warn(message, { error: (err.message || err.statusMessage) });
}
});
}
getRealmToVacuum(files) {
const upperLimit = Math.min(10, files.length);
const index = Math.floor(Math.random() * upperLimit);
return files.sorted("lastVacuumed")[index];
}
shouldRun(files) {
const lastVacuumedRealm = files.sorted("lastVacuumed", true)[0];
if (!lastVacuumedRealm) {
this.logger.debug("Skipping vacuum because all Realms have been vacuumed recently.");
return false;
}
const timeSinceLastVacuum = moment().diff(moment(lastVacuumedRealm.lastVacuumed), "second");
if (lastVacuumedRealm.lastVacuumed && timeSinceLastVacuum < this.interval) {
this.logger.debug(`Skipping vacuum because a Realm with path '${lastVacuumedRealm.path}' ` +
`was vacuumed ${timeSinceLastVacuum} seconds ago which is less than the interval of ${this.interval}s.`);
return false;
}
this.logger.debug(`Will run vacuum because the last vacuumed Realm ('${lastVacuumedRealm.path}') ` +
(lastVacuumedRealm.lastVacuumed
? `was vacuumed ${timeSinceLastVacuum} seconds ago which is more than the interval of ${this.interval}s`
: "has never been vacuumed"));
return true;
}
}
exports.RealmHoover = RealmHoover;
//# sourceMappingURL=RealmHoover.js.map