feat: 增加afterHooks处理

pull/56/head
moonrailgun 3 years ago
parent 214666113c
commit 79557a7399

@ -2,3 +2,8 @@
* id
*/
export const SYSTEM_USERID = '000000000000000000000000';
/**
*
*/
export const CONFIG_GATEWAY_AFTER_HOOK = '$gatewayAfterHooks';

@ -18,6 +18,8 @@ import type { TFunction } from 'i18next';
import { t } from './lib/i18n';
import type { ValidationRuleObject } from 'fastest-validator';
import type { BuiltinEventMap } from '../structs/events';
import { CONFIG_GATEWAY_AFTER_HOOK } from '../const';
import _ from 'lodash';
type ServiceActionHandler<T = any> = (
ctx: TcPureContext<any>
@ -68,6 +70,12 @@ interface TcServiceBroker extends ServiceBroker {
groups?: string | string[]
): Promise<void>;
emit(eventName: string): Promise<void>;
broadcast<K extends string>(
eventName: K,
data: K extends keyof BuiltinEventMap ? BuiltinEventMap[K] : unknown,
groups?: string | string[]
): Promise<void>;
broadcast(eventName: string): Promise<void>;
}
/**
@ -87,6 +95,11 @@ export abstract class TcService extends Service {
private _settings: ServiceSchema['settings'] = {};
private _events: ServiceSchema['events'] = {};
/**
*
*/
public globalConfig: Record<string, any> = {};
private _generateAndParseSchema() {
this.parseServiceSchema({
name: this.serviceName,
@ -104,6 +117,8 @@ export abstract class TcService extends Service {
this.onInit(); // 初始化服务
this.initBuiltin(); // 初始化内部服务
this._generateAndParseSchema();
this.logger = this.buildLoggerWithPrefix(this.logger);
@ -119,6 +134,17 @@ export abstract class TcService extends Service {
protected async onStop() {}
protected initBuiltin() {
this.registerEventListener('config.updated', (payload) => {
this.logger.info('Update global config with:', payload.config);
if (payload.config) {
this.globalConfig = {
...payload.config,
};
}
});
}
registerMixin(mixin: Partial<ServiceSchema>): void {
this._mixins.push(mixin);
}
@ -257,6 +283,29 @@ export abstract class TcService extends Service {
return super.waitForServices(serviceNames, timeout, interval, logger);
}
getGlobalConfig(key: string): any {
return _.get(this.globalConfig, key);
}
/**
*
*/
async setGlobalConfig(key: string, value: any): Promise<void> {
await this.waitForServices('config');
await this.broker.call('config.set', {
key,
value,
});
}
async registryAfterActionHook(actionName: string, callbackAction: string) {
await this.waitForServices(['gateway', 'config']);
await this.broker.call('config.addToSet', {
key: `${CONFIG_GATEWAY_AFTER_HOOK}.${actionName}`,
value: `${this.serviceName}.${callbackAction}`,
});
}
/**
* action
* NOTICE: 使Redisservice

@ -21,4 +21,5 @@ export interface BuiltinEventMap {
messageId: string;
meta: MessageMetaStruct;
};
'config.updated': { config: Record<string, any> };
}

@ -1,10 +1,11 @@
import _ from 'lodash';
import { TcService, TcPureContext, config } from 'tailchat-server-sdk';
/**
*
*/
class ConfigService extends TcService {
config = {};
config = {}; // 自管理的配置项globalConfig是同步过来的
get serviceName(): string {
return 'config';
@ -33,6 +34,13 @@ class ConfigService extends TcService {
value: 'any',
},
});
this.registerAction('addToSet', this.addToSet, {
visibility: 'public',
params: {
key: 'string',
value: 'any',
},
});
this.registerAuthWhitelist(['/config/client']);
}
@ -56,11 +64,23 @@ class ConfigService extends TcService {
return this.config[ctx.params.key] ?? null;
}
async set(ctx: TcPureContext<{ key: string; value: string }>) {
async set(ctx: TcPureContext<{ key: string; value: any }>) {
const { key, value } = ctx.params;
this.config[key] = value;
await this.broker.broadcast('config.updated', this.config);
_.set(this.config, key, value);
await this.broker.broadcast('config.updated', { config: this.config });
}
/**
*
*/
async addToSet(ctx: TcPureContext<{ key: string; value: any }>) {
const { key, value } = ctx.params;
const originConfig = _.get(this.config, key) ?? [];
_.set(this.config, key, _.uniq([...originConfig, value]));
await this.broker.broadcast('config.updated', { config: this.config });
}
}

@ -10,6 +10,7 @@ import {
parseLanguageFromHead,
builtinAuthWhitelist,
PureContext,
CONFIG_GATEWAY_AFTER_HOOK,
} from 'tailchat-server-sdk';
import { TcHealth } from '../../mixins/health.mixin';
import type { Readable } from 'stream';
@ -169,6 +170,20 @@ export default class ApiService extends TcService {
// Async function which return with Promise
res.setHeader('X-Node-ID', ctx.nodeID);
if (ctx.action.name) {
const afterHooks = this.getGlobalConfig(
`${CONFIG_GATEWAY_AFTER_HOOK}.${ctx.action.name}`
); // TODO: 这里actionName可能不对。需要调试
if (Array.isArray(afterHooks) && afterHooks.length > 0) {
for (const action of afterHooks) {
this.broker.call(String(action), {
route,
data,
});
}
}
}
if (data && data['__raw']) {
if (data['header']) {
Object.entries(data['header']).forEach(([key, value]) => {

Loading…
Cancel
Save