mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-25 08:58:23 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into more-coverage
This commit is contained in:
@@ -9,7 +9,7 @@ import { getReputation } from "./reputation";
|
||||
|
||||
interface CanSubmitResult {
|
||||
canSubmit: boolean;
|
||||
reason?: string;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
async function lowDownvotes(userID: HashedUserID): Promise<boolean> {
|
||||
@@ -27,11 +27,13 @@ export async function canSubmit(userID: HashedUserID, category: Category): Promi
|
||||
lowDownvotes(userID),
|
||||
(async () => (await getReputation(userID)) > config.minReputationToSubmitChapter)(),
|
||||
hasFeature(userID, Feature.ChapterSubmitter)
|
||||
])
|
||||
]),
|
||||
reason: "Submitting chapters requires a minimum reputation. You can ask on Discord/Matrix to get permission with less reputation."
|
||||
};
|
||||
default:
|
||||
return {
|
||||
canSubmit: true
|
||||
canSubmit: true,
|
||||
reason: ""
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -25,19 +25,40 @@ let exportClient: RedisSB = {
|
||||
quit: () => new Promise((resolve) => resolve(null)),
|
||||
};
|
||||
|
||||
let lastClientFail = 0;
|
||||
let lastReadFail = 0;
|
||||
let activeRequests = 0;
|
||||
|
||||
if (config.redis?.enabled) {
|
||||
Logger.info("Connected to redis");
|
||||
const client = createClient(config.redis);
|
||||
const readClient = config.redisRead?.enabled ? createClient(config.redisRead) : null;
|
||||
void client.connect(); // void as we don't care about the promise
|
||||
void readClient?.connect();
|
||||
exportClient = client as RedisSB;
|
||||
|
||||
|
||||
const get = client.get.bind(client);
|
||||
const getRead = readClient?.get?.bind(readClient);
|
||||
exportClient.get = (key) => new Promise((resolve, reject) => {
|
||||
activeRequests++;
|
||||
const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null;
|
||||
get(key).then((reply) => {
|
||||
const chosenGet = pickChoice(get, getRead);
|
||||
chosenGet(key).then((reply) => {
|
||||
if (timeout !== null) clearTimeout(timeout);
|
||||
|
||||
activeRequests--;
|
||||
resolve(reply);
|
||||
}).catch((err) => reject(err));
|
||||
}).catch((err) => {
|
||||
if (chosenGet === get) {
|
||||
lastClientFail = Date.now();
|
||||
} else {
|
||||
lastReadFail = Date.now();
|
||||
}
|
||||
|
||||
activeRequests--;
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
exportClient.increment = (key) => new Promise((resolve, reject) =>
|
||||
void client.multi()
|
||||
@@ -48,11 +69,35 @@ if (config.redis?.enabled) {
|
||||
.catch((err) => reject(err))
|
||||
);
|
||||
client.on("error", function(error) {
|
||||
lastClientFail = Date.now();
|
||||
Logger.error(`Redis Error: ${error}`);
|
||||
});
|
||||
client.on("reconnect", () => {
|
||||
Logger.info("Redis: trying to reconnect");
|
||||
});
|
||||
readClient?.on("error", function(error) {
|
||||
lastReadFail = Date.now();
|
||||
Logger.error(`Redis Read-Only Error: ${error}`);
|
||||
});
|
||||
readClient?.on("reconnect", () => {
|
||||
Logger.info("Redis Read-Only: trying to reconnect");
|
||||
});
|
||||
}
|
||||
|
||||
function pickChoice<T>(client: T, readClient: T): T {
|
||||
const readAvailable = !!readClient;
|
||||
const ignoreReadDueToFailure = lastReadFail > Date.now() - 1000 * 30;
|
||||
const readDueToFailure = lastClientFail > Date.now() - 1000 * 30;
|
||||
if (readAvailable && !ignoreReadDueToFailure && (readDueToFailure ||
|
||||
Math.random() > 1 / (config.redisRead?.weight + 1))) {
|
||||
return readClient;
|
||||
} else {
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
export function getRedisActiveRequests(): number {
|
||||
return activeRequests;
|
||||
}
|
||||
|
||||
export default exportClient;
|
||||
|
||||
Reference in New Issue
Block a user