mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2024-11-10 09:07:47 +01:00
Add concurrent request limit
This commit is contained in:
parent
f6c68ec29c
commit
f6f83fcbe4
3 changed files with 36 additions and 3 deletions
|
@ -76,7 +76,8 @@ addDefaults(config, {
|
|||
port: 5432,
|
||||
max: 10,
|
||||
idleTimeoutMillis: 10000,
|
||||
maxTries: 3
|
||||
maxTries: 3,
|
||||
maxConcurrentRequests: 3500
|
||||
},
|
||||
postgresReadOnly: {
|
||||
enabled: false,
|
||||
|
@ -89,7 +90,8 @@ addDefaults(config, {
|
|||
max: 10,
|
||||
idleTimeoutMillis: 10000,
|
||||
maxTries: 3,
|
||||
fallbackOnFail: true
|
||||
fallbackOnFail: true,
|
||||
maxConcurrentRequests: 3500
|
||||
},
|
||||
dumpDatabase: {
|
||||
enabled: false,
|
||||
|
|
|
@ -33,6 +33,9 @@ export class Postgres implements IDatabase {
|
|||
private poolRead: Pool;
|
||||
private lastPoolReadFail = 0;
|
||||
|
||||
private concurrentRequests = 0;
|
||||
private concurrentReadRequests = 0;
|
||||
|
||||
constructor(private config: DatabaseConfig) {}
|
||||
|
||||
async init(): Promise<void> {
|
||||
|
@ -99,8 +102,23 @@ export class Postgres implements IDatabase {
|
|||
|
||||
Logger.debug(`prepare (postgres): type: ${type}, query: ${query}, params: ${params}`);
|
||||
|
||||
const pendingQueries: PromiseWithState<QueryResult<any>>[] = [];
|
||||
if (this.config.readOnly) {
|
||||
if (this.concurrentReadRequests > this.config.postgresReadOnly?.maxConcurrentRequests) {
|
||||
Logger.error(`prepare (postgres): cancelling read query because too many concurrent requests, query: ${query}`);
|
||||
throw new Error("Too many concurrent requests");
|
||||
}
|
||||
|
||||
this.concurrentReadRequests++;
|
||||
} else {
|
||||
if (this.concurrentRequests > this.config.postgres.maxConcurrentRequests) {
|
||||
Logger.error(`prepare (postgres): cancelling query because too many concurrent requests, query: ${query}`);
|
||||
throw new Error("Too many concurrent requests");
|
||||
}
|
||||
|
||||
this.concurrentRequests++;
|
||||
}
|
||||
|
||||
const pendingQueries: PromiseWithState<QueryResult<any>>[] = [];
|
||||
let tries = 0;
|
||||
let lastPool: Pool = null;
|
||||
const maxTries = () => (lastPool === this.pool
|
||||
|
@ -116,6 +134,12 @@ export class Postgres implements IDatabase {
|
|||
if (options.useReplica && maxTries() - tries > 1) currentPromises.push(savePromiseState(timeoutPomise(this.config.postgresReadOnly.readTimeout)));
|
||||
const queryResult = await nextFulfilment(currentPromises);
|
||||
|
||||
if (this.config.readOnly) {
|
||||
this.concurrentReadRequests--;
|
||||
} else {
|
||||
this.concurrentRequests--;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "get": {
|
||||
const value = queryResult.rows[0];
|
||||
|
@ -143,6 +167,12 @@ export class Postgres implements IDatabase {
|
|||
}
|
||||
} while (this.isReadQuery(type) && tries < maxTries());
|
||||
|
||||
if (this.config.readOnly) {
|
||||
this.concurrentReadRequests--;
|
||||
} else {
|
||||
this.concurrentRequests--;
|
||||
}
|
||||
|
||||
throw new Error(`prepare (postgres): ${type} ${query} failed after ${tries} tries`);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ interface RedisConfig extends redis.RedisClientOptions {
|
|||
export interface CustomPostgresConfig extends PoolConfig {
|
||||
enabled: boolean;
|
||||
maxTries: number;
|
||||
maxConcurrentRequests: number;
|
||||
}
|
||||
|
||||
export interface CustomPostgresReadOnlyConfig extends CustomPostgresConfig {
|
||||
|
|
Loading…
Reference in a new issue