diff --git a/site/docs/advanced/cluster-client.md b/site/docs/advanced/cluster-client.md index bbe6b834f2..a36a72b683 100644 --- a/site/docs/advanced/cluster-client.md +++ b/site/docs/advanced/cluster-client.md @@ -70,7 +70,7 @@ We abstract the client interface into the following two broad categories, which Client example ```js -const Base = require('sdk-base'); +const { Base } = require('sdk-base'); class Client extends Base { constructor(options) { @@ -168,8 +168,8 @@ In the following I will use a simple example to introduce how to make a client s ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor(options) { @@ -236,7 +236,7 @@ class RegistryClient extends Base { if (changed) { this.emit( key, - this._registered.get(key).map((url) => URL.parse(url, true)), + this._registered.get(key).map((url) => parse(url, true)), ); } } diff --git a/site/docs/advanced/cluster-client.zh-CN.md b/site/docs/advanced/cluster-client.zh-CN.md index 9e6ba1a33a..df39c9e324 100644 --- a/site/docs/advanced/cluster-client.zh-CN.md +++ b/site/docs/advanced/cluster-client.zh-CN.md @@ -69,7 +69,7 @@ win / +------------------+ \ lose 客户端示例 ```js -const Base = require('sdk-base'); +const { Base } = require('sdk-base'); class Client extends Base { constructor(options) { @@ -165,8 +165,8 @@ Leader 和 Follower 通过下面的协议进行数据交换: ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor(options) { @@ -233,7 +233,7 @@ class RegistryClient extends Base { if (changed) { this.emit( key, - this._registered.get(key).map(url => URL.parse(url, true)), + this._registered.get(key).map(url => parse(url, true)), ); } } @@ -554,4 +554,4 @@ class APIClient extends APIClientBase { } module.exports = APIClient; -``` \ No newline at end of file +``` diff --git a/test/cluster1/cluster-client.test.ts b/test/cluster1/cluster-client.test.ts index bdea52dfb7..cbbd71b0df 100644 --- a/test/cluster1/cluster-client.test.ts +++ b/test/cluster1/cluster-client.test.ts @@ -1,4 +1,5 @@ import { strict as assert } from 'node:assert'; +import { scheduler } from 'node:timers/promises'; import { mm } from '@eggjs/mock'; import { MockApplication, createApp, singleProcessApp } from '../utils.js'; @@ -15,45 +16,35 @@ describe('test/cluster1/cluster-client.test.ts', () => { after(async () => { await app.close(); const agentInnerClient = app.agent.registryClient[innerClient]; - assert(agentInnerClient._realClient.closed === true); - mm.restore(); + assert.equal(agentInnerClient._realClient.closed, true); + await mm.restore(); }); - it('should publish & subscribe', () => { - return app.httpRequest() + it('should publish & subscribe', async () => { + await app.httpRequest() .post('/publish') .send({ value: 'www.testme.com' }) .expect('ok') - .expect(200) - .then(() => { - return new Promise(resolve => { - setTimeout(resolve, 500); - }); - }) - .then(() => { - return app.httpRequest() - .get('/getHosts') - .expect('www.testme.com:20880') - .expect(200); - }); + .expect(200); + await scheduler.wait(500); + await app.httpRequest() + .get('/getHosts') + .expect('www.testme.com:20880') + .expect(200); }); - it('should get default cluster response timeout', () => { - return app.httpRequest() + it('should get default cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getDefaultTimeout') - .expect(200) - .then(res => { - assert(res.text === '60000'); - }); + .expect(200); + assert.equal(res.text, '60000'); }); - it('should get overwrite cluster response timeout', () => { - return app.httpRequest() + it('should get overwrite cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getOverwriteTimeout') - .expect(200) - .then(res => { - assert(res.text === '1000'); - }); + .expect(200); + assert.equal(res.text, '1000'); }); }); @@ -65,45 +56,35 @@ describe('test/cluster1/cluster-client.test.ts', () => { after(async () => { await app.close(); const agentInnerClient = app.agent.registryClient[innerClient]; - assert(agentInnerClient._realClient.closed === true); + assert.equal(agentInnerClient._realClient.closed, true); mm.restore(); }); - it('should publish & subscribe', () => { - return app.httpRequest() + it('should publish & subscribe', async () => { + await app.httpRequest() .post('/publish') .send({ value: 'www.testme.com' }) .expect('ok') - .expect(200) - .then(() => { - return new Promise(resolve => { - setTimeout(resolve, 500); - }); - }) - .then(() => { - return app.httpRequest() - .get('/getHosts') - .expect('www.testme.com:20880') - .expect(200); - }); + .expect(200); + await scheduler.wait(500); + await app.httpRequest() + .get('/getHosts') + .expect('www.testme.com:20880') + .expect(200); }); - it('should get default cluster response timeout', () => { - return app.httpRequest() + it('should get default cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getDefaultTimeout') - .expect(200) - .then(res => { - assert(res.text === '60000'); - }); + .expect(200); + assert.equal(res.text, '60000'); }); - it('should get overwrite cluster response timeout', () => { - return app.httpRequest() + it('should get overwrite cluster response timeout', async () => { + const res = await app.httpRequest() .get('/getOverwriteTimeout') - .expect(200) - .then(res => { - assert(res.text === '1000'); - }); + .expect(200); + assert.equal(res.text, '1000'); }); }); }); diff --git a/test/fixtures/apps/cluster_mod_app/agent.js b/test/fixtures/apps/cluster_mod_app/agent.js index 1abc3bc6c6..9142c8ffb8 100644 --- a/test/fixtures/apps/cluster_mod_app/agent.js +++ b/test/fixtures/apps/cluster_mod_app/agent.js @@ -2,18 +2,26 @@ const ApiClient = require('./lib/api_client'); const ApiClient2 = require('./lib/api_client_2'); const RegistryClient = require('./lib/registry_client'); -module.exports = function(agent) { - agent.registryClient = agent.cluster(RegistryClient).create(); - agent.apiClient = new ApiClient({ - cluster: agent.cluster, - }); - agent.apiClient2 = new ApiClient2({ - cluster: agent.cluster, - }); +module.exports = class Boot { + constructor(agent) { + this.agent = agent; + } - agent.beforeStart(async function() { + async didLoad() { + const agent = this.agent; + agent.registryClient = agent.cluster(RegistryClient).create(); + agent.apiClient = new ApiClient({ + cluster: agent.cluster, + }); + agent.apiClient2 = new ApiClient2({ + cluster: agent.cluster, + }); + } + + async willReady() { + const agent = this.agent; await agent.registryClient.ready(); await agent.apiClient.ready(); await agent.apiClient2.ready(); - }); + } }; diff --git a/test/fixtures/apps/cluster_mod_app/lib/registry_client.js b/test/fixtures/apps/cluster_mod_app/lib/registry_client.js index e5969ff3a8..c97a72418a 100644 --- a/test/fixtures/apps/cluster_mod_app/lib/registry_client.js +++ b/test/fixtures/apps/cluster_mod_app/lib/registry_client.js @@ -1,7 +1,5 @@ -'use strict'; - -const URL = require('url'); -const Base = require('sdk-base'); +const { parse } = require('node:url'); +const { Base } = require('sdk-base'); class RegistryClient extends Base { constructor() { @@ -45,7 +43,7 @@ class RegistryClient extends Base { } else { this._registered.set(key, [reg.publishData]); } - this.emit(key, this._registered.get(key).map(url => new URL.parse(url, true))); + this.emit(key, this._registered.get(key).map(url => parse(url, true))); } close() { diff --git a/test/lib/core/messenger/local.test.ts b/test/lib/core/messenger/local.test.ts index ebac375cbc..8b1126eb80 100644 --- a/test/lib/core/messenger/local.test.ts +++ b/test/lib/core/messenger/local.test.ts @@ -1,10 +1,10 @@ import { strict as assert } from 'node:assert'; import { mm } from '@eggjs/mock'; import { pending } from 'pedding'; -import { singleProcessApp, MockApplication } from '../../../utils.js'; +import { singleProcessApp, SingleModeApplication } from '../../../utils.js'; describe('test/lib/core/messenger/local.test.ts', () => { - let app: MockApplication; + let app: SingleModeApplication; before(async () => { app = await singleProcessApp('apps/demo'); @@ -144,10 +144,11 @@ describe('test/lib/core/messenger/local.test.ts', () => { done(); }); - let res = app.messenger.sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); + // keep compatible with old code, use process.pid as number + let res = (app.messenger as any).sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); assert(res === app.messenger); // should ignore if target process is not self - res = app.messenger.sendTo(1, 'sendTo-event', { foo: 'bar' }); + res = app.messenger.sendTo('1', 'sendTo-event', { foo: 'bar' }); assert(res === app.messenger); }); @@ -162,7 +163,7 @@ describe('test/lib/core/messenger/local.test.ts', () => { done(); }); - app.agent.messenger.sendTo(process.pid, 'sendTo-event', { foo: 'bar' }); + app.agent.messenger.sendTo(String(process.pid), 'sendTo-event', { foo: 'bar' }); }); }); @@ -201,7 +202,7 @@ describe('test/lib/core/messenger/local.test.ts', () => { describe('onMessage()', () => { it('should ignore if message format error', () => { - app.messenger.onMessage(); + (app.messenger as any).onMessage(); app.messenger.onMessage('foo'); app.messenger.onMessage({ action: 1 }); }); diff --git a/test/utils.ts b/test/utils.ts index ac06760b4d..d7d254d23f 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -13,6 +13,7 @@ import { Application as Koa } from '@eggjs/koa'; import { request } from '@eggjs/supertest'; import { startEgg, StartEggOptions, + type SingleModeAgent, } from '../src/index.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -24,6 +25,10 @@ export async function rimraf(target: string) { } export { MockApplication, MockOptions, MockClusterOptions, mm }; +export interface SingleModeApplication extends MockApplication { + agent: SingleModeAgent; +} + export const restore = () => mm.restore(); export function app(name: string | MockOptions, options?: MockOptions) { @@ -54,7 +59,7 @@ export function cluster(name: string | MockClusterOptions, options?: MockCluster * @param {Object} [options] - optional * @return {App} app - Application object. */ -export async function singleProcessApp(baseDir: string, options: StartEggOptions = {}): Promise { +export async function singleProcessApp(baseDir: string, options: StartEggOptions = {}): Promise { if (!baseDir.startsWith('/')) { baseDir = path.join(__dirname, 'fixtures', baseDir); } @@ -62,7 +67,7 @@ export async function singleProcessApp(baseDir: string, options: StartEggOptions options.baseDir = baseDir; const app = await startEgg(options); Reflect.set(app, 'httpRequest', () => request(app.callback())); - return app as unknown as MockApplication; + return app as unknown as SingleModeApplication; } let localServer: http.Server | undefined;