Files
tubestation/storage/test/unit/VacuumParticipant.sys.mjs
Marco Bonardo 1786dc2a9c Bug 1813986 - Add an asyncVacuum() method to storage async connections, and let VacuumManager use it. r=asuth
Add asyncVacuum to mozIStorageAsyncConnection, that dispatches a runnable to
the helper thread, where it will execute a full or incremental vacuum, depending
on the connection auto_vacuum value.
It also supports vacuuming attached schemas.
asyncVacuum() supports changing both the page_size and auto_vacuum.
Change mozIStorageVacuumParticipant to return a mozIStorageAsyncConnection and
allow specifying whether incremental vacuum should be enabled.
Change vacuumManager notification from heavy-io-task to vacuum-begin and vacuum-end
since the original proposal of notifying heavy IO didn't take off.
Cleanup test_vacuum to be able to use instances of the test VacuumParticipant,
that means we can remove the no more necessary registerESM hack.
Fix Places History as the only cpp consumer.

Differential Revision: https://phabricator.services.mozilla.com/D168298
2023-03-22 15:36:37 +00:00

110 lines
2.9 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// This testing component is used in test_vacuum* tests.
const CAT_NAME = "vacuum-participant";
const CONTRACT_ID = "@unit.test.com/test-vacuum-participant;1";
import { MockRegistrar } from "resource://testing-common/MockRegistrar.sys.mjs";
import { TestUtils } from "resource://testing-common/TestUtils.sys.mjs";
export class VacuumParticipant {
#dbConn;
#expectedPageSize = 0;
#useIncrementalVacuum = false;
#grant = false;
/**
* Build a VacuumParticipant instance.
* Note: After creation you must await instance.promiseRegistered() to ensure
* Category Caches have been updated.
*
* @param {mozIStorageAsyncConnection} databaseConnection
* The connection to be vacuumed.
* @param {Number} [expectedPageSize]
* Used to change the database page size.
* @param {boolean} [useIncrementalVacuum]
* Whether to enable incremental vacuum on the database.
* @param {boolean} [grant]
* Whether the vacuum operation should be granted.
*/
constructor(
databaseConnection,
{ expectedPageSize = 0, useIncrementalVacuum = false, grant = true } = {}
) {
this.#dbConn = databaseConnection;
// Register as the only participant.
this.#unregisterAllParticipants();
this.#registerAsParticipant();
this.#expectedPageSize = expectedPageSize;
this.#useIncrementalVacuum = useIncrementalVacuum;
this.#grant = grant;
this.QueryInterface = ChromeUtils.generateQI([
"mozIStorageVacuumParticipant",
]);
}
promiseRegistered() {
// The category manager dispatches change notifications to the main thread,
// so we must wait one tick.
return TestUtils.waitForTick();
}
#registerAsParticipant() {
MockRegistrar.register(CONTRACT_ID, this);
Services.catMan.addCategoryEntry(
CAT_NAME,
"vacuumParticipant",
CONTRACT_ID,
false,
false
);
}
#unregisterAllParticipants() {
// First unregister other participants.
for (let { data: entry } of Services.catMan.enumerateCategory(CAT_NAME)) {
Services.catMan.deleteCategoryEntry("vacuum-participant", entry, false);
}
}
async dispose() {
this.#unregisterAllParticipants();
MockRegistrar.unregister(CONTRACT_ID);
await new Promise(resolve => {
this.#dbConn.asyncClose(resolve);
});
}
get expectedDatabasePageSize() {
return this.#expectedPageSize;
}
get useIncrementalVacuum() {
return this.#useIncrementalVacuum;
}
get databaseConnection() {
return this.#dbConn;
}
onBeginVacuum() {
if (!this.#grant) {
return false;
}
Services.obs.notifyObservers(null, "test-begin-vacuum");
return true;
}
onEndVacuum(succeeded) {
Services.obs.notifyObservers(
null,
succeeded ? "test-end-vacuum-success" : "test-end-vacuum-failure"
);
}
}