oak-backend-base 4.1.6 → 4.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/AppLoader.d.ts +5 -3
- package/lib/AppLoader.js +22 -8
- package/lib/ClusterAppLoader.d.ts +2 -2
- package/lib/ClusterAppLoader.js +7 -7
- package/package.json +3 -3
package/lib/AppLoader.d.ts
CHANGED
|
@@ -15,15 +15,17 @@ export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt exten
|
|
|
15
15
|
protected dataSubscriber?: DataSubscriber<ED, Cxt>;
|
|
16
16
|
protected synchronizer?: Synchronizer<ED, Cxt>;
|
|
17
17
|
protected contextBuilder: (store: DbStore<ED, Cxt>) => Cxt;
|
|
18
|
+
private nsSocket?;
|
|
18
19
|
private requireSth;
|
|
19
20
|
protected makeContext(cxtStr?: string, headers?: IncomingHttpHeaders): Promise<Cxt>;
|
|
20
21
|
/**
|
|
21
22
|
* 后台启动的configuration,统一放在这里读取
|
|
22
23
|
*/
|
|
23
24
|
private getConfiguration;
|
|
24
|
-
constructor(path: string,
|
|
25
|
+
constructor(path: string, nsSubscribe?: Namespace, nsSocket?: Namespace, nsServer?: Namespace);
|
|
25
26
|
protected registerTrigger(trigger: Trigger<ED, keyof ED, Cxt>): void;
|
|
26
|
-
initTriggers(): void;
|
|
27
|
+
protected initTriggers(): void;
|
|
28
|
+
protected initSocket(): void;
|
|
27
29
|
mount(initialize?: true): Promise<void>;
|
|
28
30
|
unmount(): Promise<void>;
|
|
29
31
|
execAspect(name: string, headers?: IncomingHttpHeaders, contextString?: string, params?: any): Promise<{
|
|
@@ -35,7 +37,7 @@ export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt exten
|
|
|
35
37
|
getStore(): DbStore<ED, Cxt>;
|
|
36
38
|
getEndpoints(prefix: string): [string, "post" | "get" | "put" | "delete", string, (params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<any>][];
|
|
37
39
|
protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt, singleton?: true): Promise<OperationResult<ED>>;
|
|
38
|
-
protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, singleton?: true): Promise<Partial<ED[T]["Schema"]>[]>;
|
|
40
|
+
protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, forUpdate?: true, singleton?: true): Promise<Partial<ED[T]["Schema"]>[]>;
|
|
39
41
|
protected execWatcher(watcher: Watcher<ED, keyof ED, Cxt>): Promise<OperationResult<ED> | undefined>;
|
|
40
42
|
protected getCheckpointTs(): number;
|
|
41
43
|
protected checkpoint(): Promise<number>;
|
package/lib/AppLoader.js
CHANGED
|
@@ -11,6 +11,7 @@ const uuid_1 = require("oak-domain/lib/utils/uuid");
|
|
|
11
11
|
const types_1 = require("oak-domain/lib/types");
|
|
12
12
|
const DbStore_1 = require("./DbStore");
|
|
13
13
|
const index_1 = tslib_1.__importStar(require("oak-common-aspect/lib/index"));
|
|
14
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
14
15
|
const dependencyBuilder_1 = require("oak-domain/lib/compiler/dependencyBuilder");
|
|
15
16
|
const DataSubscriber_1 = tslib_1.__importDefault(require("./cluster/DataSubscriber"));
|
|
16
17
|
const env_1 = require("./cluster/env");
|
|
@@ -22,6 +23,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
22
23
|
dataSubscriber;
|
|
23
24
|
synchronizer;
|
|
24
25
|
contextBuilder;
|
|
26
|
+
nsSocket;
|
|
25
27
|
requireSth(filePath) {
|
|
26
28
|
const depFilePath = (0, path_1.join)(this.path, filePath);
|
|
27
29
|
let sth;
|
|
@@ -65,7 +67,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
65
67
|
syncConfig: syncConfigs,
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
|
-
constructor(path,
|
|
70
|
+
constructor(path, nsSubscribe, nsSocket, nsServer) {
|
|
69
71
|
super(path);
|
|
70
72
|
const { dbConfig } = this.getConfiguration();
|
|
71
73
|
const { storageSchema } = require(`${path}/lib/oak-app-domain/Storage`);
|
|
@@ -74,9 +76,10 @@ class AppLoader extends types_1.AppLoader {
|
|
|
74
76
|
const { authDeduceRelationMap, selectFreeEntities, updateFreeDict } = this.requireSth('lib/configuration/relation');
|
|
75
77
|
this.aspectDict = Object.assign({}, index_1.default, this.requireSth('lib/aspects/index'));
|
|
76
78
|
this.dbStore = new DbStore_1.DbStore(storageSchema, () => this.contextBuilder(this.dbStore), dbConfig, authDeduceRelationMap, selectFreeEntities, updateFreeDict);
|
|
77
|
-
if (
|
|
78
|
-
this.dataSubscriber = new DataSubscriber_1.default(
|
|
79
|
+
if (nsSubscribe) {
|
|
80
|
+
this.dataSubscriber = new DataSubscriber_1.default(nsSubscribe, nsServer);
|
|
79
81
|
}
|
|
82
|
+
this.nsSocket = nsSocket;
|
|
80
83
|
const { BackendRuntimeContext } = require(`${path}/lib/context/BackendRuntimeContext`);
|
|
81
84
|
const loaderThis = this;
|
|
82
85
|
// 需要重载context上的构造和commit方法,否则程序中执行context.restartToExecute这样的方法中,new一个context出来是无法正确执行的
|
|
@@ -123,6 +126,14 @@ class AppLoader extends types_1.AppLoader {
|
|
|
123
126
|
syncTriggers.forEach((trigger) => this.registerTrigger(trigger));
|
|
124
127
|
}
|
|
125
128
|
}
|
|
129
|
+
initSocket() {
|
|
130
|
+
// todo
|
|
131
|
+
const socketFilePath = (0, path_1.join)(this.path, 'lib/socket/index');
|
|
132
|
+
if ((0, fs_1.existsSync)(socketFilePath)) {
|
|
133
|
+
const { registerSocketEntry } = require(socketFilePath);
|
|
134
|
+
(0, assert_1.default)(typeof registerSocketEntry === 'function');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
126
137
|
async mount(initialize) {
|
|
127
138
|
const { path } = this;
|
|
128
139
|
if (!initialize) {
|
|
@@ -131,6 +142,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
131
142
|
this.synchronizer = new Synchronizer_1.default(syncConfig, this.dbStore.getSchema(), () => this.contextBuilder(this.dbStore));
|
|
132
143
|
}
|
|
133
144
|
this.initTriggers();
|
|
145
|
+
this.initSocket();
|
|
134
146
|
}
|
|
135
147
|
const { importations, exportations } = require(`${path}/lib/ports/index`);
|
|
136
148
|
(0, index_1.registerPorts)(importations || [], exportations || []);
|
|
@@ -273,10 +285,10 @@ class AppLoader extends types_1.AppLoader {
|
|
|
273
285
|
operateInWatcher(entity, operation, context, singleton) {
|
|
274
286
|
return this.dbStore.operate(entity, operation, context, {});
|
|
275
287
|
}
|
|
276
|
-
selectInWatcher(entity, selection, context, singleton) {
|
|
288
|
+
selectInWatcher(entity, selection, context, forUpdate, singleton) {
|
|
277
289
|
return this.dbStore.select(entity, selection, context, {
|
|
278
290
|
blockTrigger: true,
|
|
279
|
-
forUpdate
|
|
291
|
+
forUpdate,
|
|
280
292
|
});
|
|
281
293
|
}
|
|
282
294
|
async execWatcher(watcher) {
|
|
@@ -295,13 +307,13 @@ class AppLoader extends types_1.AppLoader {
|
|
|
295
307
|
}, context, singleton);
|
|
296
308
|
}
|
|
297
309
|
else {
|
|
298
|
-
const { entity, projection, fn, filter, singleton } = watcher;
|
|
310
|
+
const { entity, projection, fn, filter, singleton, forUpdate } = watcher;
|
|
299
311
|
const filter2 = typeof filter === 'function' ? await filter() : (0, lodash_1.cloneDeep)(filter);
|
|
300
312
|
const projection2 = typeof projection === 'function' ? await projection() : (0, lodash_1.cloneDeep)(projection);
|
|
301
313
|
const rows = await this.selectInWatcher(entity, {
|
|
302
314
|
data: projection2,
|
|
303
315
|
filter: filter2,
|
|
304
|
-
}, context, singleton);
|
|
316
|
+
}, context, forUpdate, singleton);
|
|
305
317
|
if (rows.length > 0) {
|
|
306
318
|
result = await fn(context, rows);
|
|
307
319
|
}
|
|
@@ -424,7 +436,9 @@ class AppLoader extends types_1.AppLoader {
|
|
|
424
436
|
const context = await this.makeContext();
|
|
425
437
|
const start = Date.now();
|
|
426
438
|
try {
|
|
427
|
-
const result = await routineFn(context
|
|
439
|
+
const result = await routineFn(context, {
|
|
440
|
+
socket: this.nsSocket,
|
|
441
|
+
});
|
|
428
442
|
console.log(`例程【${name}】执行成功,耗时${Date.now() - start}毫秒,结果是【${result}】`);
|
|
429
443
|
await context.commit();
|
|
430
444
|
}
|
|
@@ -10,10 +10,10 @@ export declare class ClusterAppLoader<ED extends EntityDict & BaseEntityDict, Cx
|
|
|
10
10
|
protected socket: Socket;
|
|
11
11
|
private connectServerSocket;
|
|
12
12
|
private sub;
|
|
13
|
-
constructor(path: string, nsDs: Namespace, nsServer: Namespace, socketPath: string);
|
|
13
|
+
constructor(path: string, nsDs: Namespace, nsSocket: Namespace, nsServer: Namespace, socketPath: string);
|
|
14
14
|
protected registerTrigger(trigger: Trigger<ED, keyof ED, Cxt>): void;
|
|
15
15
|
protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt, singleton?: true): Promise<OperationResult<ED>>;
|
|
16
|
-
protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, singleton?: true): Promise<Partial<ED[T]['Schema']>[]>;
|
|
16
|
+
protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, forUpdate?: true, singleton?: true): Promise<Partial<ED[T]['Schema']>[]>;
|
|
17
17
|
protected execWatcher(watcher: Watcher<ED, keyof ED, Cxt>): Promise<OperationResult<ED> | undefined>;
|
|
18
18
|
protected execFreeTimer(timer: FreeTimer<ED, Cxt>, context: Cxt): Promise<OperationResult<ED>> | undefined;
|
|
19
19
|
protected checkpoint(): Promise<number>;
|
package/lib/ClusterAppLoader.js
CHANGED
|
@@ -48,8 +48,8 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
48
48
|
this.socket.connect();
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
constructor(path, nsDs, nsServer, socketPath) {
|
|
52
|
-
super(path, nsDs, nsServer);
|
|
51
|
+
constructor(path, nsDs, nsSocket, nsServer, socketPath) {
|
|
52
|
+
super(path, nsDs, nsSocket, nsServer);
|
|
53
53
|
this.dbStore.setOnVolatileTrigger(async (entity, trigger, ids, cxtStr, option) => {
|
|
54
54
|
const execLocal = async (ids2) => {
|
|
55
55
|
const context = await this.makeContext(cxtStr);
|
|
@@ -72,7 +72,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
72
72
|
if (trigger.cs) {
|
|
73
73
|
// 如果是cluster sensative的触发器,需要发送到相应的instance上被处理
|
|
74
74
|
const context = await this.makeContext();
|
|
75
|
-
const rows = await context.select(entity, {
|
|
75
|
+
const rows = !!(ids.length) ? await context.select(entity, {
|
|
76
76
|
data: {
|
|
77
77
|
id: 1,
|
|
78
78
|
$$seq$$: 1,
|
|
@@ -80,7 +80,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
80
80
|
filter: {
|
|
81
81
|
id: { $in: ids },
|
|
82
82
|
}
|
|
83
|
-
}, { dontCollect: true });
|
|
83
|
+
}, { dontCollect: true }) : [];
|
|
84
84
|
await context.commit();
|
|
85
85
|
const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
|
|
86
86
|
const grouped = (0, lodash_1.groupBy)(rows, (ele) => ele.$$seq$$ % instanceCount);
|
|
@@ -101,7 +101,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
101
101
|
if ((0, env_1.getClusterInfo)().instanceId === 0) {
|
|
102
102
|
await execLocal(ids);
|
|
103
103
|
}
|
|
104
|
-
else {
|
|
104
|
+
else if (ids.length) {
|
|
105
105
|
if (process.env.NODE_ENV === 'development') {
|
|
106
106
|
console.log(`在trigger「${trigger.name}」上,因为singleton原因,数据「${ids.join(',')}」将被推送到「0」号进程操作(当前进程号是「${(0, env_1.getClusterInfo)().instanceId}」)`);
|
|
107
107
|
}
|
|
@@ -145,7 +145,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
145
145
|
filter: filter2,
|
|
146
146
|
}, context);
|
|
147
147
|
}
|
|
148
|
-
selectInWatcher(entity, selection, context, singleton) {
|
|
148
|
+
selectInWatcher(entity, selection, context, forUpdate, singleton) {
|
|
149
149
|
const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
|
|
150
150
|
(0, assert_1.default)(instanceCount && typeof instanceId === 'number');
|
|
151
151
|
const { filter } = selection;
|
|
@@ -157,7 +157,7 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
157
157
|
return super.selectInWatcher(entity, {
|
|
158
158
|
...selection,
|
|
159
159
|
filter: filter2,
|
|
160
|
-
}, context);
|
|
160
|
+
}, context, forUpdate);
|
|
161
161
|
}
|
|
162
162
|
async execWatcher(watcher) {
|
|
163
163
|
if (watcher.singleton && (0, env_1.getClusterInfo)().instanceId !== 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-backend-base",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.8",
|
|
4
4
|
"description": "oak-backend-base",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"author": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"node-schedule": "^2.1.0",
|
|
23
23
|
"oak-common-aspect": "^3.0.2",
|
|
24
24
|
"oak-db": "^3.3.2",
|
|
25
|
-
"oak-domain": "^5.1.
|
|
26
|
-
"oak-frontend-base": "^5.3.
|
|
25
|
+
"oak-domain": "^5.1.9",
|
|
26
|
+
"oak-frontend-base": "^5.3.18",
|
|
27
27
|
"socket.io": "^4.7.2",
|
|
28
28
|
"socket.io-client": "^4.7.2",
|
|
29
29
|
"uuid": "^8.3.2"
|