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.
@@ -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, ns?: Namespace, nsServer?: Namespace);
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, ns, nsServer) {
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 (ns) {
78
- this.dataSubscriber = new DataSubscriber_1.default(ns, nsServer);
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: true,
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>;
@@ -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.6",
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.4",
26
- "oak-frontend-base": "^5.3.12",
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"