Do more to shut down quickly and start RSS feeds later (#671)

* Only load RSS feeds once all connections have loaded

* Clear various timeouts

* changelog
This commit is contained in:
Will Hunt 2023-03-24 14:13:51 +00:00 committed by GitHub
parent 5d27f173a6
commit f6475a5182
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 12 deletions

1
changelog.d/671.bugfix Normal file
View File

@ -0,0 +1 @@
Ensure Hookshot shuts down faster when running feeds.

View File

@ -52,6 +52,7 @@ export class Bridge {
private github?: GithubInstance; private github?: GithubInstance;
private adminRooms: Map<string, AdminRoom> = new Map(); private adminRooms: Map<string, AdminRoom> = new Map();
private widgetApi?: BridgeWidgetApi; private widgetApi?: BridgeWidgetApi;
private feedReader?: FeedReader;
private provisioningApi?: Provisioner; private provisioningApi?: Provisioner;
private replyProcessor = new RichRepliesPreprocessor(true); private replyProcessor = new RichRepliesPreprocessor(true);
@ -77,6 +78,8 @@ export class Bridge {
} }
public stop() { public stop() {
this.feedReader?.stop();
this.tokenStore.stop();
this.as.stop(); this.as.stop();
if (this.queue.stop) this.queue.stop(); if (this.queue.stop) this.queue.stop();
} }
@ -129,17 +132,6 @@ export class Bridge {
this.github, this.github,
); );
if (this.config.feeds?.enabled) {
new FeedReader(
this.config.feeds,
this.connectionManager,
this.queue,
// Use default bot when storing account data
this.as.botClient,
);
}
if (this.config.provisioning) { if (this.config.provisioning) {
const routers = []; const routers = [];
if (this.config.jira) { if (this.config.jira) {
@ -756,6 +748,19 @@ export class Bridge {
} }
await queue.onIdle(); await queue.onIdle();
log.info(`All connections loaded`); log.info(`All connections loaded`);
// Load feeds after connections, to limit the chances of us double
// posting to rooms if a previous hookshot instance is being replaced.
if (this.config.feeds?.enabled) {
this.feedReader = new FeedReader(
this.config.feeds,
this.connectionManager,
this.queue,
// Use default bot when storing account data
this.as.botClient,
);
}
await this.as.begin(); await this.as.begin();
log.info(`Bridge is now ready. Found ${this.connectionManager.size} connections`); log.info(`Bridge is now ready. Found ${this.connectionManager.size} connections`);
this.ready = true; this.ready = true;

View File

@ -81,6 +81,12 @@ export class UserTokenStore extends TypedEmitter<Emitter> {
this.key = await fs.readFile(this.keyPath); this.key = await fs.readFile(this.keyPath);
} }
public stop() {
for (const session of this.oauthSessionStore.values()) {
clearTimeout(session.timeout);
}
}
public async storeUserToken(type: TokenType, userId: string, token: string, instanceUrl?: string): Promise<void> { public async storeUserToken(type: TokenType, userId: string, token: string, instanceUrl?: string): Promise<void> {
if (!this.config.checkPermission(userId, type, BridgePermissionLevel.login)) { if (!this.config.checkPermission(userId, type, BridgePermissionLevel.login)) {
throw new ApiError('User does not have permission to log in to service', ErrCode.ForbiddenUser); throw new ApiError('User does not have permission to log in to service', ErrCode.ForbiddenUser);

View File

@ -111,6 +111,9 @@ export class FeedReader {
static readonly seenEntriesEventType = "uk.half-shot.matrix-hookshot.feed.reader.seenEntries"; static readonly seenEntriesEventType = "uk.half-shot.matrix-hookshot.feed.reader.seenEntries";
private shouldRun = true;
private timeout?: NodeJS.Timeout;
constructor( constructor(
private readonly config: BridgeConfigFeeds, private readonly config: BridgeConfigFeeds,
private readonly connectionManager: ConnectionManager, private readonly connectionManager: ConnectionManager,
@ -140,6 +143,11 @@ export class FeedReader {
}); });
} }
public stop() {
clearTimeout(this.timeout);
this.shouldRun = false;
}
private calculateFeedUrls(): void { private calculateFeedUrls(): void {
// just in case we got an invalid URL somehow // just in case we got an invalid URL somehow
const normalizedUrls = []; const normalizedUrls = [];
@ -305,7 +313,11 @@ export class FeedReader {
log.debug(`Feed fetching took ${elapsed / 1000}s, sleeping for ${sleepFor / 1000}s`); log.debug(`Feed fetching took ${elapsed / 1000}s, sleeping for ${sleepFor / 1000}s`);
} }
setTimeout(() => {
this.timeout = setTimeout(() => {
if (!this.shouldRun) {
return;
}
void this.pollFeeds(); void this.pollFeeds();
}, sleepFor); }, sleepFor);
} }