endpoint在热重载时出现异常的容错处理

This commit is contained in:
pqcqaq 2025-01-18 13:48:04 +08:00
parent 4d8473d67f
commit 05dedacde3
6 changed files with 64 additions and 58 deletions

View File

@ -253,29 +253,38 @@ class AppLoader extends types_1.AppLoader {
const transformEndpointItem = (key, item) => {
const { name, method, fn, params: itemParams } = item;
const k = `${key}-${name}-${method}`;
const makeEndpoint = async () => {
endPointMap[k] = true;
let url = `${prefix}/${key}`;
if (itemParams) {
for (const p of itemParams) {
url += `/:${p}`;
}
}
endPointRouters.push([name, method, url, async (params, headers, req, body) => {
const context = await this.makeContext(undefined, headers);
try {
const result = await fn(context, params, headers, req, body);
await context.commit();
return result;
}
catch (err) {
await context.rollback();
console.error(`endpoint「${key}」方法「${method}」出错`, err);
throw err;
}
}]);
};
if (endPointMap[k]) {
if (process.env.NODE_ENV === 'development') {
// 这里发现在热重载模式下会出现报错debug跟到requireSth发现问题怀疑是node的require机制导致的先加个容错在其他环境肯定不会出现
console.warn(`endpoint中url为「${key}」、名为${name}的方法「${method}」存在重复定义,将进行覆盖`);
makeEndpoint();
return;
}
throw new Error(`endpoint中url为「${key}」、名为${name}的方法「${method}」存在重复定义`);
}
endPointMap[k] = true;
let url = `${prefix}/${key}`;
if (itemParams) {
for (const p of itemParams) {
url += `/:${p}`;
}
}
endPointRouters.push([name, method, url, async (params, headers, req, body) => {
const context = await this.makeContext(undefined, headers);
try {
const result = await fn(context, params, headers, req, body);
await context.commit();
return result;
}
catch (err) {
await context.rollback();
console.error(`endpoint「${key}」方法「${method}」出错`, err);
throw err;
}
}]);
makeEndpoint();
};
if (endpoints) {
for (const router in endpoints) {

View File

@ -114,6 +114,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
});
this.csTriggers = {};
const { name } = nsServer;
// 本机pm2的socketio连接在cli中连接到adaptor之后会被自然推到redis这边继续保持pm2的socketio连接即可
const socketUrl = `http://localhost:${process.env.PM2_PORT || 8080}${name}`;
this.socket = (0, socket_io_client_1.io)(socketUrl, {
path: socketPath,

View File

@ -19,5 +19,4 @@ export default class DataSubscriber<ED extends EntityDict & BaseEntityDict, Cont
private startup;
publishEvent(event: string, records: OpRecord<ED>[], sid?: string): void;
publishServerEvent(identifier: string, event: string, ...rest: any[]): void;
private sendStartupMessage;
}

View File

@ -60,7 +60,6 @@ class DataSubscriber {
}
});
}
this.sendStartupMessage();
}
publishEvent(event, records, sid) {
const { instanceId } = (0, env_1.getClusterInfo)();
@ -76,18 +75,5 @@ class DataSubscriber {
(0, console_1.assert)(this.nsServer);
this.nsServer.to(identifier).emit(event, ...rest);
}
// 添加一个新的方法,用于发送启动消息
sendStartupMessage() {
const { instanceId } = (0, env_1.getClusterInfo)();
const event = 'startupEvent';
const message = `Instance ${instanceId} started`;
// 使用 nsServer 命名空间发布事件
if (this.nsServer) {
this.nsServer.emit(event, message);
}
else {
console.warn('nsServer is not available');
}
}
}
exports.default = DataSubscriber;

View File

@ -35,10 +35,12 @@ function initialize() {
const usingCluster = true;
const instanceId = parseInt(instanceIdStr);
const instanceCount = parseInt(getProcessEnvOption('OAK_INSTANCE_CNT'));
const enableRedis = getProcessEnvOption('OAK_ENABLE_REDIS') === 'true';
return {
usingCluster,
instanceCount,
instanceId,
enableRedis,
};
}
return {

View File

@ -314,32 +314,41 @@ export class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends Backe
const transformEndpointItem = (key: string, item: EndpointItem<ED, Cxt>) => {
const { name, method, fn, params: itemParams } = item;
const k = `${key}-${name}-${method}`;
const makeEndpoint = async () => {
endPointMap[k] = true;
let url = `${prefix}/${key}`;
if (itemParams) {
for (const p of itemParams) {
url += `/:${p}`;
}
}
endPointRouters.push(
[name, method, url, async (params, headers, req, body) => {
const context = await this.makeContext(undefined, headers);
try {
const result = await fn(context, params, headers, req, body);
await context.commit();
return result;
}
catch (err) {
await context.rollback();
console.error(`endpoint「${key}」方法「${method}」出错`, err);
throw err;
}
}]
);
}
if (endPointMap[k]) {
if (process.env.NODE_ENV === 'development') {
// 这里发现在热重载模式下会出现报错debug跟到requireSth发现问题怀疑是node的require机制导致的先加个容错在其他环境肯定不会出现
console.warn(`endpoint中url为「${key}」、名为${name}的方法「${method}」存在重复定义,将进行覆盖`);
makeEndpoint();
return;
}
throw new Error(`endpoint中url为「${key}」、名为${name}的方法「${method}」存在重复定义`);
}
endPointMap[k] = true;
let url = `${prefix}/${key}`;
if (itemParams) {
for (const p of itemParams) {
url += `/:${p}`;
}
}
endPointRouters.push(
[name, method, url, async (params, headers, req, body) => {
const context = await this.makeContext(undefined, headers);
try {
const result = await fn(context, params, headers, req, body);
await context.commit();
return result;
}
catch (err) {
await context.rollback();
console.error(`endpoint「${key}」方法「${method}」出错`, err);
throw err;
}
}]
);
makeEndpoint();
};
if (endpoints) {
for (const router in endpoints) {