4.8.12 test fix (#2988)

* perf: qps limit

* perf: http response data

* perf: json path check

* fix: ts

* loop support reference parent variable
This commit is contained in:
Archer
2024-10-25 16:34:26 +08:00
committed by shilin66
parent eb28734a63
commit 8df886452e
14 changed files with 144 additions and 122 deletions

View File

@@ -19,8 +19,11 @@ export const NextEntry = ({ beforeCallback = [] }: { beforeCallback?: Promise<an
await Promise.all([withNextCors(req, res), ...beforeCallback]);
let response = null;
for (const handler of args) {
for await (const handler of args) {
response = await handler(req, res);
if (res.writableFinished) {
break;
}
}
// Get request duration

View File

@@ -1,26 +0,0 @@
import { ApiRequestProps } from 'type/next';
import requestIp from 'request-ip';
import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode';
import { authFrequencyLimit } from 'common/system/frequencyLimit/utils';
import { addSeconds } from 'date-fns';
// unit: times/s
// how to use?
// export default NextAPI(useQPSLimit(10), handler); // limit 10 times per second for a ip
export function useQPSLimit(limit: number) {
return async (req: ApiRequestProps) => {
const ip = requestIp.getClientIp(req);
if (!ip) {
return;
}
try {
await authFrequencyLimit({
eventId: 'ip-qps-limit' + ip,
maxAmount: limit,
expiredTime: addSeconds(new Date(), 1)
});
} catch (_) {
return Promise.reject(ERROR_ENUM.QPSLimitExceed);
}
};
}

View File

@@ -0,0 +1,32 @@
import { ApiRequestProps } from '../../type/next';
import requestIp from 'request-ip';
import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode';
import { authFrequencyLimit } from '../system/frequencyLimit/utils';
import { addSeconds } from 'date-fns';
import { NextApiResponse } from 'next';
import { jsonRes } from '../response';
// unit: times/s
// how to use?
// export default NextAPI(useQPSLimit(10), handler); // limit 10 times per second for a ip
export function useReqFrequencyLimit(seconds: number, limit: number) {
return async (req: ApiRequestProps, res: NextApiResponse) => {
const ip = requestIp.getClientIp(req);
if (!ip && process.env.USE_IP_LIMIT !== 'true') {
return;
}
try {
await authFrequencyLimit({
eventId: 'ip-qps-limit' + ip,
maxAmount: limit,
expiredTime: addSeconds(new Date(), seconds)
});
} catch (_) {
res.status(429);
jsonRes(res, {
code: 429,
message: ERROR_ENUM.tooManyRequest
});
}
};
}

View File

@@ -17,7 +17,7 @@ const FrequencyLimitSchema = new Schema({
});
try {
FrequencyLimitSchema.index({ eventId: 1 }, { unique: true });
FrequencyLimitSchema.index({ eventId: 1, expiredTime: 1 });
FrequencyLimitSchema.index({ expiredTime: 1 }, { expireAfterSeconds: 0 });
} catch (error) {}

View File

@@ -1,6 +1,5 @@
import { AuthFrequencyLimitProps } from '@fastgpt/global/common/frequenctLimit/type';
import { MongoFrequencyLimit } from './schema';
import { readFromSecondary } from '../../mongo/utils';
export const authFrequencyLimit = async ({
eventId,
@@ -11,22 +10,24 @@ export const authFrequencyLimit = async ({
// 对应 eventId 的 account+1, 不存在的话,则创建一个
const result = await MongoFrequencyLimit.findOneAndUpdate(
{
eventId
eventId,
expiredTime: { $gte: new Date() }
},
{
$inc: { amount: 1 },
// If not exist, set the expiredTime
$setOnInsert: { expiredTime }
},
{
upsert: true,
new: true,
...readFromSecondary
new: true
}
);
).lean();
// 因为始终会返回+1的结果所以这里不能直接等需要多一个。
if (result.amount > maxAmount) {
return Promise.reject(result);
}
} catch (error) {}
} catch (error) {
console.log(error);
}
};