diff --git a/src/Draupnir.ts b/src/Draupnir.ts index 10142e49..972ceb7c 100644 --- a/src/Draupnir.ts +++ b/src/Draupnir.ts @@ -102,7 +102,6 @@ export class Draupnir implements Client { if (config.pollReports) { this.reportPoller = new ReportPoller(this, this.reportManager); } - this.clientRooms.on('timeline', this.timelineEventListener); this.commandContext = { draupnir: this, roomID: this.managementRoomID, client: this.client, reactionHandler: this.reactionHandler, clientPlatform: this.clientPlatform @@ -283,8 +282,13 @@ export class Draupnir implements Client { } } + /** + * Start responding to events. + * This will not start the appservice from listening and responding + * to events. Nor will it start any syncing client. + */ public async start(): Promise { - // FIXME: This method needs to be removed it probably won't be called at all. + this.clientRooms.on('timeline', this.timelineEventListener); if (this.reportPoller) { const reportPollSetting = await ReportPoller.getReportPollSetting( this.client, @@ -294,6 +298,11 @@ export class Draupnir implements Client { } } + public stop(): void { + this.clientRooms.off('timeline', this.timelineEventListener); + this.reportPoller?.stop() + } + public createRoomReference(roomID: StringRoomID): MatrixRoomID { return new MatrixRoomID( roomID, diff --git a/src/draupnirfactory/DraupnirClientRooms.ts b/src/draupnirfactory/DraupnirClientRooms.ts deleted file mode 100644 index f7013141..00000000 --- a/src/draupnirfactory/DraupnirClientRooms.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (C) 2023-2024 Gnuxie - * All rights reserved. - */ - -import { ActionException, ActionExceptionKind, ActionResult, ClientRooms, JoinedRoomsRevision, JoinedRoomsSafe, Ok, RoomStateManager, StandardClientRooms, StandardJoinedRoomsRevision, StringUserID, isError } from "matrix-protection-suite"; - -export class DraupnirClientRooms extends StandardClientRooms implements ClientRooms { - private constructor( - roomStateManager: RoomStateManager, - joinedRoomsThunk: JoinedRoomsSafe, - clientUserID: StringUserID, - joinedRoomsRevision: JoinedRoomsRevision - ) { - super( - roomStateManager, - joinedRoomsThunk, - clientUserID, - joinedRoomsRevision - ); - } - - public static async makeClientRooms( - roomStateManager: RoomStateManager, - joinedRoomsThunk: JoinedRoomsSafe, - clientUserID: StringUserID, - ): Promise> { - try { - const joinedRooms = await joinedRoomsThunk(); - if (isError(joinedRooms)) { - return joinedRooms; - } - const revision = StandardJoinedRoomsRevision.blankRevision( - clientUserID - ).reviseFromJoinedRooms(joinedRooms.ok); - return Ok(new DraupnirClientRooms( - roomStateManager, - joinedRoomsThunk, - clientUserID, - revision - )) - } catch (exception) { - return ActionException.Result( - `Couldn't create client rooms`, - { - exception, - exceptionKind: ActionExceptionKind.Unknown - } - ) - } - } -} diff --git a/src/draupnirfactory/DraupnirFactory.ts b/src/draupnirfactory/DraupnirFactory.ts index 946644ea..43b23814 100644 --- a/src/draupnirfactory/DraupnirFactory.ts +++ b/src/draupnirfactory/DraupnirFactory.ts @@ -6,7 +6,6 @@ import { ActionResult, ClientsInRoomMap, MatrixRoomID, Ok, StringUserID, isError } from "matrix-protection-suite"; import { Draupnir } from "../Draupnir"; import { ClientCapabilityFactory, ClientForUserID, RoomStateManagerFactory, joinedRoomsSafe } from "matrix-protection-suite-for-matrix-bot-sdk"; -import { DraupnirClientRooms } from "./DraupnirClientRooms"; import { IConfig } from "../config"; import { makeProtectedRoomsSet } from "./DraupnirProtectedRoomsSet"; @@ -25,15 +24,13 @@ export class DraupnirFactory { const policyRoomManager = await this.roomStateManagerFactory.getPolicyRoomManager(clientUserID); const roomMembershipManager = await this.roomStateManagerFactory.getRoomMembershipManager(clientUserID); const client = await this.clientProvider(clientUserID); - const clientRooms = await DraupnirClientRooms.makeClientRooms( - roomStateManager, + const clientRooms = await this.clientsInRoomMap.makeClientRooms( + clientUserID, async () => joinedRoomsSafe(client), - clientUserID ); if (isError(clientRooms)) { return clientRooms; } - this.clientsInRoomMap.addClientRooms(clientRooms.ok); const clientPlatform = this.clientCapabilityFactory.makeClientPlatform(clientUserID, client); const protectedRoomsSet = await makeProtectedRoomsSet( managementRoom, diff --git a/src/draupnirfactory/StandardDraupnirManager.ts b/src/draupnirfactory/StandardDraupnirManager.ts index 589379af..817198e1 100644 --- a/src/draupnirfactory/StandardDraupnirManager.ts +++ b/src/draupnirfactory/StandardDraupnirManager.ts @@ -105,7 +105,7 @@ export class StandardDraupnirManager { if (draupnir === undefined) { throw new TypeError(`Trying to start a draupnir that hasn't been created ${clientUserID}`); } - this.clientsInRooms.addClientRooms(draupnir.clientRooms); + draupnir.start(); this.listeningDraupnirs.set(clientUserID, draupnir); this.readyDraupnirs.delete(clientUserID); } @@ -117,7 +117,7 @@ export class StandardDraupnirManager { if (draupnir === undefined) { return; } else { - this.clientsInRooms.removeClientRooms(draupnir.clientRooms); + draupnir.stop(); this.listeningDraupnirs.delete(clientUserID); this.readyDraupnirs.set(clientUserID, draupnir); } diff --git a/src/index.ts b/src/index.ts index b801958d..3c094e6c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,7 @@ import { constructWebAPIs, makeDraupnirBotModeFromConfig } from "./DraupnirBotMo import { Draupnir } from "./Draupnir"; import { SafeMatrixEmitterWrapper } from "matrix-protection-suite-for-matrix-bot-sdk"; import { DefaultEventDecoder } from "matrix-protection-suite"; +import { WebAPIs } from "./webapis/WebAPIs"; (async function () { @@ -68,6 +69,7 @@ import { DefaultEventDecoder } from "matrix-protection-suite"; } let bot: Draupnir | null = null; + let apis: WebAPIs | null = null; try { const storagePath = path.isAbsolute(config.dataPath) ? config.dataPath : path.join(__dirname, '../', config.dataPath); const storage = new SimpleFsStorageProvider(path.join(storagePath, "bot.json")); @@ -90,6 +92,7 @@ import { DefaultEventDecoder } from "matrix-protection-suite"; config.RUNTIME.client = client; bot = await makeDraupnirBotModeFromConfig(client, new SafeMatrixEmitterWrapper(client, DefaultEventDecoder), config); + apis = constructWebAPIs(bot); } catch (err) { console.error(`Failed to setup mjolnir from the config ${config.dataPath}: ${err}`); throw err; @@ -97,11 +100,12 @@ import { DefaultEventDecoder } from "matrix-protection-suite"; try { await bot.start(); await config.RUNTIME.client.start(); - const apis = constructWebAPIs(bot); await apis.start(); healthz.isHealthy = true; } catch (err) { console.error(`Mjolnir failed to start: ${err}`); + bot.stop(); + apis.stop(); throw err; } })(); diff --git a/test/integration/fixtures.ts b/test/integration/fixtures.ts index 72d4389d..e8f5b570 100644 --- a/test/integration/fixtures.ts +++ b/test/integration/fixtures.ts @@ -38,6 +38,7 @@ export const mochaHooks = { this.timeout(10000) this.apis?.stop(); draupnirClient()?.stop(); + this.draupnir?.stop(); // remove alias from management room and leave it. if (this.draupnir !== undefined) {