oak-backend-base 4.1.26 → 4.1.27
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 +3 -2
- package/lib/AppLoader.js +45 -5
- package/lib/ClusterAppLoader.d.ts +3 -2
- package/lib/ClusterAppLoader.js +8 -2
- package/package.json +3 -3
package/lib/AppLoader.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
|
2
|
-
import { AppLoader as GeneralAppLoader, Trigger, EntityDict, Watcher, OpRecord, FreeTimer, OperationResult } from "oak-domain/lib/types";
|
|
2
|
+
import { AppLoader as GeneralAppLoader, Trigger, EntityDict, Watcher, OpRecord, FreeTimer, OperationResult, BaseTimer } from "oak-domain/lib/types";
|
|
3
3
|
import { BackendRuntimeContext } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
|
|
4
4
|
import { IncomingHttpHeaders, IncomingMessage } from 'http';
|
|
5
5
|
import { Namespace } from 'socket.io';
|
|
@@ -59,7 +59,8 @@ export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt exten
|
|
|
59
59
|
protected getCheckpointTs(): number;
|
|
60
60
|
protected checkpoint(): Promise<number>;
|
|
61
61
|
startWatchers(): void;
|
|
62
|
-
protected
|
|
62
|
+
protected execBaseTimer(timer: BaseTimer<ED, Cxt>, context: Cxt): Promise<OperationResult<ED>> | undefined;
|
|
63
|
+
protected execFreeTimer(timer: FreeTimer<ED, Cxt>, contextBuilder: () => Promise<Cxt>): Promise<OperationResult<ED>> | undefined;
|
|
63
64
|
startTimers(): void;
|
|
64
65
|
execStartRoutines(): Promise<void>;
|
|
65
66
|
execStopRoutines(): Promise<void>;
|
package/lib/AppLoader.js
CHANGED
|
@@ -57,13 +57,12 @@ class AppLoader extends types_1.AppLoader {
|
|
|
57
57
|
* 发布内部错误事件给注册的处理器
|
|
58
58
|
*/
|
|
59
59
|
async publishInternalError(type, message, err) {
|
|
60
|
-
const errorToPublish = (0, lodash_1.cloneDeep)(err);
|
|
61
60
|
await Promise.all(this.internalErrorHandlers.map((handler) => {
|
|
62
61
|
return new Promise(async (resolve) => {
|
|
63
62
|
const ctx = await this.makeContext();
|
|
64
63
|
try {
|
|
65
64
|
console.log(`调用internalErrorHandler【${handler.name}】处理内部错误事件`);
|
|
66
|
-
await handler.handle(ctx, type, message,
|
|
65
|
+
await handler.handle(ctx, type, message, err);
|
|
67
66
|
await ctx.commit();
|
|
68
67
|
}
|
|
69
68
|
catch (e) {
|
|
@@ -370,8 +369,22 @@ class AppLoader extends types_1.AppLoader {
|
|
|
370
369
|
});
|
|
371
370
|
}
|
|
372
371
|
async execWatcher(watcher) {
|
|
373
|
-
const context = await this.makeContext();
|
|
374
372
|
let result;
|
|
373
|
+
if (watcher.hasOwnProperty('type') && watcher.type === 'free') {
|
|
374
|
+
const selectContext = await this.makeContext();
|
|
375
|
+
const { entity, projection, fn, filter, singleton, forUpdate } = watcher;
|
|
376
|
+
const filter2 = typeof filter === 'function' ? await filter() : (0, lodash_1.cloneDeep)(filter);
|
|
377
|
+
const projection2 = typeof projection === 'function' ? await projection() : (0, lodash_1.cloneDeep)(projection);
|
|
378
|
+
const rows = await this.selectInWatcher(entity, {
|
|
379
|
+
data: projection2,
|
|
380
|
+
filter: filter2,
|
|
381
|
+
}, selectContext, forUpdate, singleton);
|
|
382
|
+
if (rows.length > 0) {
|
|
383
|
+
result = await fn(() => this.makeContext(), rows);
|
|
384
|
+
}
|
|
385
|
+
return result;
|
|
386
|
+
}
|
|
387
|
+
const context = await this.makeContext();
|
|
375
388
|
try {
|
|
376
389
|
if (watcher.hasOwnProperty('actionData')) {
|
|
377
390
|
const { entity, action, filter, actionData, singleton } = watcher;
|
|
@@ -423,7 +436,13 @@ class AppLoader extends types_1.AppLoader {
|
|
|
423
436
|
const { watchers: adWatchers } = (0, IntrinsicLogics_1.makeIntrinsicLogics)(this.dbStore.getSchema(), ActionDefDict);
|
|
424
437
|
const totalWatchers = (watchers || []).concat(adWatchers);
|
|
425
438
|
let count = 0;
|
|
439
|
+
const skipOnceSet = new Set();
|
|
426
440
|
const execOne = async (watcher, start) => {
|
|
441
|
+
if (skipOnceSet.has(watcher.name)) {
|
|
442
|
+
skipOnceSet.delete(watcher.name);
|
|
443
|
+
console.log(`跳过本次执行watcher【${watcher.name}】`);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
427
446
|
try {
|
|
428
447
|
const result = await this.execWatcher(watcher);
|
|
429
448
|
if (result) {
|
|
@@ -455,12 +474,22 @@ class AppLoader extends types_1.AppLoader {
|
|
|
455
474
|
}
|
|
456
475
|
this.watcherTimerId = setTimeout(() => doWatchers(), 120000);
|
|
457
476
|
};
|
|
477
|
+
// 首次执行时,跳过所有lazy的watcher
|
|
478
|
+
for (const w of totalWatchers) {
|
|
479
|
+
if (w.lazy) {
|
|
480
|
+
skipOnceSet.add(w.name);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
458
483
|
doWatchers();
|
|
459
484
|
}
|
|
460
|
-
|
|
485
|
+
execBaseTimer(timer, context) {
|
|
461
486
|
const { timer: timerFn } = timer;
|
|
462
487
|
return timerFn(context);
|
|
463
488
|
}
|
|
489
|
+
execFreeTimer(timer, contextBuilder) {
|
|
490
|
+
const { timer: timerFn } = timer;
|
|
491
|
+
return timerFn(contextBuilder);
|
|
492
|
+
}
|
|
464
493
|
startTimers() {
|
|
465
494
|
const timers = this.requireSth('lib/timers/index');
|
|
466
495
|
if (timers) {
|
|
@@ -480,9 +509,20 @@ class AppLoader extends types_1.AppLoader {
|
|
|
480
509
|
}
|
|
481
510
|
}
|
|
482
511
|
else {
|
|
512
|
+
if (timer.hasOwnProperty('type') && timer.type === 'free') {
|
|
513
|
+
try {
|
|
514
|
+
const result = await this.execFreeTimer(timer, () => this.makeContext());
|
|
515
|
+
console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒,结果是`, result);
|
|
516
|
+
}
|
|
517
|
+
catch (err) {
|
|
518
|
+
console.error(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
|
|
519
|
+
this.publishInternalError(`timer`, `定时器【${name}】执行失败`, err);
|
|
520
|
+
}
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
483
523
|
const context = await this.makeContext();
|
|
484
524
|
try {
|
|
485
|
-
const result = await this.
|
|
525
|
+
const result = await this.execBaseTimer(timer, context);
|
|
486
526
|
if (result) {
|
|
487
527
|
console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒,结果是`, result);
|
|
488
528
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
|
2
|
-
import { EntityDict, OperationResult, Trigger, Watcher, FreeTimer } from 'oak-domain/lib/types';
|
|
2
|
+
import { EntityDict, OperationResult, Trigger, Watcher, FreeTimer, BaseTimer } from 'oak-domain/lib/types';
|
|
3
3
|
import { BackendRuntimeContext } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
|
|
4
4
|
import { AppLoader } from './AppLoader';
|
|
5
5
|
import { Namespace } from 'socket.io';
|
|
@@ -15,6 +15,7 @@ export declare class ClusterAppLoader<ED extends EntityDict & BaseEntityDict, Cx
|
|
|
15
15
|
protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt, singleton?: true): Promise<OperationResult<ED>>;
|
|
16
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
|
-
protected
|
|
18
|
+
protected execBaseTimer(timer: BaseTimer<ED, Cxt>, context: Cxt): Promise<OperationResult<ED>> | undefined;
|
|
19
|
+
protected execFreeTimer(timer: FreeTimer<ED, Cxt>, contextBuilder: () => Promise<Cxt>): Promise<OperationResult<ED>> | undefined;
|
|
19
20
|
protected checkpoint(): Promise<number>;
|
|
20
21
|
}
|
package/lib/ClusterAppLoader.js
CHANGED
|
@@ -168,11 +168,17 @@ class ClusterAppLoader extends AppLoader_1.AppLoader {
|
|
|
168
168
|
}
|
|
169
169
|
return super.execWatcher(watcher);
|
|
170
170
|
}
|
|
171
|
-
|
|
171
|
+
execBaseTimer(timer, context) {
|
|
172
172
|
if (timer.singleton && (0, env_1.getClusterInfo)().instanceId !== 0) {
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
|
-
return super.
|
|
175
|
+
return super.execBaseTimer(timer, context);
|
|
176
|
+
}
|
|
177
|
+
execFreeTimer(timer, contextBuilder) {
|
|
178
|
+
if (timer.singleton && (0, env_1.getClusterInfo)().instanceId !== 0) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
return super.execFreeTimer(timer, contextBuilder);
|
|
176
182
|
}
|
|
177
183
|
async checkpoint() {
|
|
178
184
|
const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-backend-base",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.27",
|
|
4
4
|
"description": "oak-backend-base",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"author": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"mysql2": "^2.3.3",
|
|
23
23
|
"node-schedule": "^2.1.0",
|
|
24
24
|
"oak-common-aspect": "^3.0.5",
|
|
25
|
-
"oak-db": "^3.3.
|
|
26
|
-
"oak-domain": "^5.1.
|
|
25
|
+
"oak-db": "^3.3.13",
|
|
26
|
+
"oak-domain": "^5.1.34",
|
|
27
27
|
"oak-frontend-base": "^5.3.45",
|
|
28
28
|
"socket.io": "^4.8.1",
|
|
29
29
|
"socket.io-client": "^4.7.2",
|