mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 03:02:19 +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) {
|
if (transaction) {
|
||||||
return await new Promise((resolve, reject) => {
|
return await new Promise((resolve, reject) => {
|
||||||
const timer = setTimeout(() => {
|
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);
|
}, 50000);
|
||||||
|
|
||||||
transaction.afterCommit(async () => {
|
transaction.afterCommit(async () => {
|
||||||
@ -46,6 +50,7 @@ export class SyncMessageManager {
|
|||||||
skipSelf: true,
|
skipSelf: true,
|
||||||
...others,
|
...others,
|
||||||
});
|
});
|
||||||
|
|
||||||
resolve(r);
|
resolve(r);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Database } from '@nocobase/database';
|
import { Database } from '@nocobase/database';
|
||||||
import { MockServer, createMockServer } from '@nocobase/test';
|
import { createMockServer, MockServer } from '@nocobase/test';
|
||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
import { parseBuilder, parseFieldAndAssociations, queryData } from '../actions/query';
|
import { parseBuilder, parseFieldAndAssociations, queryData } from '../actions/query';
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ describe('formatter', () => {
|
|||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
app = await createMockServer({
|
app = await createMockServer({
|
||||||
acl: true,
|
acl: true,
|
||||||
plugins: ['users', 'auth', 'data-visualization'],
|
plugins: ['users', 'auth', 'field-sort', 'data-visualization'],
|
||||||
});
|
});
|
||||||
db = app.db;
|
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);
|
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 () => {
|
it('should list application with status', async () => {
|
||||||
const sub1 = `td_${uid()}`;
|
const sub1 = `td_${uid()}`;
|
||||||
await db.getRepository('applications').create({
|
await db.getRepository('applications').create({
|
||||||
|
@ -29,6 +29,12 @@ export class ApplicationModel extends Model {
|
|||||||
name: appName,
|
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) {
|
async handleSyncMessage(message) {
|
||||||
const { type } = message;
|
const { type } = message;
|
||||||
|
|
||||||
if (type === 'startApp') {
|
if (type === 'subAppStarted') {
|
||||||
const { appName } = message;
|
const { appName } = message;
|
||||||
const model = await this.app.db.getRepository('applications').findOne({
|
const model = await this.app.db.getRepository('applications').findOne({
|
||||||
filter: {
|
filter: {
|
||||||
@ -158,6 +158,10 @@ export class PluginMultiAppManagerServer extends Plugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AppSupervisor.getInstance().hasApp(appName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const subApp = model.registerToSupervisor(this.app, {
|
const subApp = model.registerToSupervisor(this.app, {
|
||||||
appOptionsFactory: this.appOptionsFactory,
|
appOptionsFactory: this.appOptionsFactory,
|
||||||
});
|
});
|
||||||
@ -208,22 +212,19 @@ export class PluginMultiAppManagerServer extends Plugin {
|
|||||||
appOptionsFactory: this.appOptionsFactory,
|
appOptionsFactory: this.appOptionsFactory,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
subApp.on('afterStart', async () => {
|
||||||
|
this.sendSyncMessage({
|
||||||
|
type: 'subAppStarted',
|
||||||
|
appName: name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// create database
|
// create database
|
||||||
await this.appDbCreator(subApp, {
|
await this.appDbCreator(subApp, {
|
||||||
transaction,
|
transaction,
|
||||||
context: options.context,
|
context: options.context,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sendSyncMessage(
|
|
||||||
{
|
|
||||||
type: 'startApp',
|
|
||||||
appName: name,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
transaction,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const startPromise = subApp.runCommand('start', '--quickstart');
|
const startPromise = subApp.runCommand('start', '--quickstart');
|
||||||
|
|
||||||
if (options?.context?.waitSubAppInstall) {
|
if (options?.context?.waitSubAppInstall) {
|
||||||
@ -289,6 +290,13 @@ export class PluginMultiAppManagerServer extends Plugin {
|
|||||||
appOptionsFactory: self.appOptionsFactory,
|
appOptionsFactory: self.appOptionsFactory,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
subApp.on('afterStart', async () => {
|
||||||
|
this.sendSyncMessage({
|
||||||
|
type: 'subAppStarted',
|
||||||
|
appName: name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// must skip load on upgrade
|
// must skip load on upgrade
|
||||||
if (!loadButNotStart) {
|
if (!loadButNotStart) {
|
||||||
await subApp.runCommand('start', '--quickstart');
|
await subApp.runCommand('start', '--quickstart');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user