fix: mongo内存泄漏

This commit is contained in:
Archer
2023-03-10 18:54:51 +08:00
parent 65da4653bc
commit 453f3be8ce
6 changed files with 69 additions and 55 deletions

View File

@@ -8,7 +8,7 @@
animation: blink 0.6s infinite; animation: blink 0.6s infinite;
} }
.animation { .animation {
:last-child::after { > :last-child::after {
display: inline-block; display: inline-block;
content: ''; content: '';
width: 4px; width: 4px;

View File

@@ -69,56 +69,51 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
stream: true stream: true
}, },
{ {
timeout: 20000,
responseType: 'stream', responseType: 'stream',
httpsAgent: openaiProxy?.httpsAgent httpsAgent: openaiProxy?.httpsAgent
} }
); );
console.log('response success');
let AIResponse = ''; let AIResponse = '';
// 解析数据 // 解析数据
const decoder = new TextDecoder(); const decoder = new TextDecoder();
new ReadableStream({ const onParse = async (event: ParsedEvent | ReconnectInterval) => {
async start(controller) { if (event.type === 'event') {
// callback const data = event.data;
async function onParse(event: ParsedEvent | ReconnectInterval) { if (data === '[DONE]') {
if (event.type === 'event') { // 存入库
const data = event.data; await ChatWindow.findByIdAndUpdate(windowId, {
if (data === '[DONE]') { $push: {
controller.close(); content: {
res.write('event: done\ndata: \n\n'); obj: 'AI',
res.end(); value: AIResponse
// 存入库 }
await ChatWindow.findByIdAndUpdate(windowId, { },
$push: { updateTime: Date.now()
content: { });
obj: 'AI', res.write('event: done\ndata: \n\n');
value: AIResponse res.end();
} return;
},
updateTime: Date.now()
});
return;
}
try {
const json = JSON.parse(data);
const content: string = json.choices[0].delta.content || '';
res.write(`event: responseData\ndata: ${content.replace(/\n/g, '<br/>')}\n\n`);
AIResponse += content;
} catch (e) {
// maybe parse error
controller.error(e);
res.end();
}
}
} }
try {
const parser = createParser(onParse); const json = JSON.parse(data);
for await (const chunk of chatResponse.data as any) { const content: string = json.choices[0].delta.content || '';
parser.feed(decoder.decode(chunk)); // console.log('content:', content)
res.write(`event: responseData\ndata: ${content.replace(/\n/g, '<br/>')}\n\n`);
AIResponse += content;
} catch (e) {
res.end();
} }
} }
}); };
const parser = createParser(onParse);
for await (const chunk of chatResponse.data as any) {
parser.feed(decoder.decode(chunk));
}
} catch (err: any) { } catch (err: any) {
let errorText = err; let errorText = err;
if (err.code === 'ECONNRESET') { if (err.code === 'ECONNRESET') {

View File

@@ -127,14 +127,14 @@ const Chat = () => {
let timer = setTimeout(() => { let timer = setTimeout(() => {
event.close(); event.close();
reject('服务器超时'); reject('服务器超时');
}, 300000); }, 30000);
event.addEventListener('responseData', ({ data }) => { event.addEventListener('responseData', ({ data }) => {
/* 重置定时器 */ /* 重置定时器 */
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(() => { timer = setTimeout(() => {
event.close(); event.close();
reject('服务器超时'); reject('服务器超时');
}, 300000); }, 30000);
const msg = data.replace(/<br\/>/g, '\n'); const msg = data.replace(/<br\/>/g, '\n');
setChatList((state) => setChatList((state) =>
@@ -264,7 +264,7 @@ const Chat = () => {
const reEdit = useCallback(async () => { const reEdit = useCallback(async () => {
if (chatList[chatList.length - 1]?.obj !== 'Human') return; if (chatList[chatList.length - 1]?.obj !== 'Human') return;
// 删除数据库最后一句 // 删除数据库最后一句
delLastMessage(windowId); await delLastMessage(windowId);
const val = chatList[chatList.length - 1].value; const val = chatList[chatList.length - 1].value;
setInputVal(val); setInputVal(val);

View File

@@ -1,18 +1,28 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import type { Mongoose } from 'mongoose';
let cachedClient: Mongoose; /**
* 连接 MongoDB 数据库
export async function connectToDatabase() { */
if (cachedClient && cachedClient.connection.readyState === 1) { export async function connectToDatabase(): Promise<void> {
return cachedClient; // @ts-ignore
if (global.mongodb) {
return;
}
// @ts-ignore
global.mongodb = 'connecting';
console.log('connect mongo');
try {
// @ts-ignore
global.mongodb = await mongoose.connect(process.env.MONGODB_URI as string, {
dbName: 'doc_gpt',
maxPoolSize: 10,
minPoolSize: 1
});
} catch (error) {
console.error('mongo connect error');
// @ts-ignore
global.mongodb = null;
} }
cachedClient = await mongoose.connect(process.env.MONGODB_URI as string, {
dbName: 'doc_gpt'
});
return cachedClient;
} }
export * from './models/authCode'; export * from './models/authCode';

9
src/types/index.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
import type { Mongoose } from 'mongoose';
declare global {
interface Global {
mongodb: Mongoose;
}
}
export type a = string;

View File

@@ -19,6 +19,6 @@
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }