mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
fix: start sub app in cluster (#5530)
* fix: start sub app * fix: test * fix: test * fix: test --------- Co-authored-by: CHENGLEI SHAO <Chareice>
This commit is contained in:
parent
746b54e9c1
commit
f81b942967
@ -37,7 +37,11 @@ export class SyncMessageManager {
|
||||
if (transaction) {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const timer = setTimeout(() => {
|
||||
reject(new Error(`Publish message to ${channel} timeout, message: ${JSON.stringify(message)}`));
|
||||
reject(
|
||||
new Error(
|
||||
`Publish message to ${channel} timeout, channel: ${channel}, message: ${JSON.stringify(message)}`,
|
||||
),
|
||||
);
|
||||
}, 50000);
|
||||
|
||||
transaction.afterCommit(async () => {
|
||||
@ -46,6 +50,7 @@ export class SyncMessageManager {
|
||||
skipSelf: true,
|
||||
...others,
|
||||
});
|
||||
|
||||
resolve(r);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import { Database } from '@nocobase/database';
|
||||
import { MockServer, createMockServer } from '@nocobase/test';
|
||||
import { createMockServer, MockServer } from '@nocobase/test';
|
||||
import compose from 'koa-compose';
|
||||
import { parseBuilder, parseFieldAndAssociations, queryData } from '../actions/query';
|
||||
|
||||
@ -19,7 +19,7 @@ describe('formatter', () => {
|
||||
beforeAll(async () => {
|
||||
app = await createMockServer({
|
||||
acl: true,
|
||||
plugins: ['users', 'auth', 'data-visualization'],
|
||||
plugins: ['users', 'auth', 'field-sort', 'data-visualization'],
|
||||
});
|
||||
db = app.db;
|
||||
});
|
||||
|
@ -0,0 +1,46 @@
|
||||
import { createMockCluster, waitSecond } from '@nocobase/test';
|
||||
import { uid } from '@nocobase/utils';
|
||||
|
||||
describe('cluster', () => {
|
||||
let cluster;
|
||||
beforeEach(async () => {
|
||||
cluster = await createMockCluster({
|
||||
plugins: ['nocobase', 'field-sort', 'multi-app-manager'],
|
||||
acl: false,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cluster.destroy();
|
||||
});
|
||||
|
||||
it('should start sub app after app created between nodes', async () => {
|
||||
const [app1, app2] = cluster.nodes;
|
||||
const name = `td_${uid()}`;
|
||||
|
||||
const fn = vi.fn();
|
||||
|
||||
app2.on('subAppStarted', async (subApp) => {
|
||||
fn(subApp.name);
|
||||
});
|
||||
|
||||
await app1.db.getRepository('applications').create({
|
||||
values: {
|
||||
name,
|
||||
options: {
|
||||
skipSupervisor: true,
|
||||
plugins: [],
|
||||
database: {
|
||||
underscored: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
context: {
|
||||
waitSubAppInstall: true,
|
||||
},
|
||||
});
|
||||
|
||||
await waitSecond(5000);
|
||||
expect(fn).toBeCalledWith(name);
|
||||
});
|
||||
});
|
@ -129,43 +129,6 @@ describe('multiple apps', () => {
|
||||
expect(await db.getRepository('applications').count()).toBe(0);
|
||||
});
|
||||
|
||||
it('should upgrade sub app', async () => {
|
||||
await db.getRepository('applications').create({
|
||||
values: {
|
||||
name: 'test1',
|
||||
options: {
|
||||
plugins: ['nocobase'],
|
||||
},
|
||||
},
|
||||
context: {
|
||||
waitSubAppInstall: true,
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('applications').create({
|
||||
values: {
|
||||
name: 'test2',
|
||||
options: {
|
||||
plugins: ['nocobase'],
|
||||
},
|
||||
},
|
||||
context: {
|
||||
waitSubAppInstall: true,
|
||||
},
|
||||
});
|
||||
|
||||
await app.runCommand('restart');
|
||||
await app.runCommand('upgrade');
|
||||
// const subAppStatus = AppSupervisor.getInstance().getAppStatus(name);
|
||||
// expect(subAppStatus).toEqual('running');
|
||||
//
|
||||
// const subApp = await AppSupervisor.getInstance().getApp(name);
|
||||
// await subApp.runCommand('upgrade');
|
||||
//
|
||||
// await AppSupervisor.getInstance().removeApp(name);
|
||||
// expect(await db.getRepository('applications').count()).toBe(1);
|
||||
});
|
||||
|
||||
it('should list application with status', async () => {
|
||||
const sub1 = `td_${uid()}`;
|
||||
await db.getRepository('applications').create({
|
||||
|
@ -29,6 +29,12 @@ export class ApplicationModel extends Model {
|
||||
name: appName,
|
||||
};
|
||||
|
||||
return new Application(subAppOptions);
|
||||
const subApp = new Application(subAppOptions);
|
||||
|
||||
subApp.on('afterStart', () => {
|
||||
mainApp.emit('subAppStarted', subApp);
|
||||
});
|
||||
|
||||
return subApp;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ export class PluginMultiAppManagerServer extends Plugin {
|
||||
async handleSyncMessage(message) {
|
||||
const { type } = message;
|
||||
|
||||
if (type === 'startApp') {
|
||||
if (type === 'subAppStarted') {
|
||||
const { appName } = message;
|
||||
const model = await this.app.db.getRepository('applications').findOne({
|
||||
filter: {
|
||||
@ -158,6 +158,10 @@ export class PluginMultiAppManagerServer extends Plugin {
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppSupervisor.getInstance().hasApp(appName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subApp = model.registerToSupervisor(this.app, {
|
||||
appOptionsFactory: this.appOptionsFactory,
|
||||
});
|
||||
@ -208,22 +212,19 @@ export class PluginMultiAppManagerServer extends Plugin {
|
||||
appOptionsFactory: this.appOptionsFactory,
|
||||
});
|
||||
|
||||
subApp.on('afterStart', async () => {
|
||||
this.sendSyncMessage({
|
||||
type: 'subAppStarted',
|
||||
appName: name,
|
||||
});
|
||||
});
|
||||
|
||||
// create database
|
||||
await this.appDbCreator(subApp, {
|
||||
transaction,
|
||||
context: options.context,
|
||||
});
|
||||
|
||||
this.sendSyncMessage(
|
||||
{
|
||||
type: 'startApp',
|
||||
appName: name,
|
||||
},
|
||||
{
|
||||
transaction,
|
||||
},
|
||||
);
|
||||
|
||||
const startPromise = subApp.runCommand('start', '--quickstart');
|
||||
|
||||
if (options?.context?.waitSubAppInstall) {
|
||||
@ -289,6 +290,13 @@ export class PluginMultiAppManagerServer extends Plugin {
|
||||
appOptionsFactory: self.appOptionsFactory,
|
||||
});
|
||||
|
||||
subApp.on('afterStart', async () => {
|
||||
this.sendSyncMessage({
|
||||
type: 'subAppStarted',
|
||||
appName: name,
|
||||
});
|
||||
});
|
||||
|
||||
// must skip load on upgrade
|
||||
if (!loadButNotStart) {
|
||||
await subApp.runCommand('start', '--quickstart');
|
||||
|
Loading…
x
Reference in New Issue
Block a user