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 adminRooms: Map<string, AdminRoom> = new Map();
private widgetApi?: BridgeWidgetApi;
private feedReader?: FeedReader;
private provisioningApi?: Provisioner;
private replyProcessor = new RichRepliesPreprocessor(true);
@ -77,6 +78,8 @@ export class Bridge {
}
public stop() {
this.feedReader?.stop();
this.tokenStore.stop();
this.as.stop();
if (this.queue.stop) this.queue.stop();
}
@ -129,17 +132,6 @@ export class Bridge {
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) {
const routers = [];
if (this.config.jira) {
@ -756,6 +748,19 @@ export class Bridge {
}
await queue.onIdle();
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();
log.info(`Bridge is now ready. Found ${this.connectionManager.size} connections`);
this.ready = true;

View File

@ -81,6 +81,12 @@ export class UserTokenStore extends TypedEmitter<Emitter> {
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> {
if (!this.config.checkPermission(userId, type, BridgePermissionLevel.login)) {
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";
private shouldRun = true;
private timeout?: NodeJS.Timeout;
constructor(
private readonly config: BridgeConfigFeeds,
private readonly connectionManager: ConnectionManager,
@ -140,6 +143,11 @@ export class FeedReader {
});
}
public stop() {
clearTimeout(this.timeout);
this.shouldRun = false;
}
private calculateFeedUrls(): void {
// just in case we got an invalid URL somehow
const normalizedUrls = [];
@ -305,7 +313,11 @@ export class FeedReader {
log.debug(`Feed fetching took ${elapsed / 1000}s, sleeping for ${sleepFor / 1000}s`);
}
setTimeout(() => {
this.timeout = setTimeout(() => {
if (!this.shouldRun) {
return;
}
void this.pollFeeds();
}, sleepFor);
}