oak-backend-base 3.2.3 → 3.3.1

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.
@@ -1,17 +1,17 @@
1
- import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
2
- import { EntityDict, OperationResult, Trigger } from 'oak-domain/lib/types';
3
- import { BackendRuntimeContext } from 'oak-frontend-base';
4
- import { AppLoader } from './AppLoader';
5
- import { DbStore } from './DbStore';
6
- import { Namespace } from 'socket.io';
7
- import { Socket } from 'socket.io-client';
8
- export declare class ClusterAppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends AppLoader<ED, Cxt> {
9
- protected socket: Socket;
10
- private csTriggers;
11
- private connect;
12
- private sub;
13
- constructor(path: string, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>, nsDs: Namespace, nsServer: Namespace, socketPath: string);
14
- protected registerTrigger(trigger: Trigger<ED, keyof ED, Cxt>): void;
15
- protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt): Promise<OperationResult<ED>>;
16
- protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt): Promise<Partial<ED[T]['Schema']>[]>;
17
- }
1
+ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
2
+ import { EntityDict, OperationResult, Trigger } from 'oak-domain/lib/types';
3
+ import { BackendRuntimeContext } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
4
+ import { AppLoader } from './AppLoader';
5
+ import { DbStore } from './DbStore';
6
+ import { Namespace } from 'socket.io';
7
+ import { Socket } from 'socket.io-client';
8
+ export declare class ClusterAppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends AppLoader<ED, Cxt> {
9
+ protected socket: Socket;
10
+ private csTriggers;
11
+ private connect;
12
+ private sub;
13
+ constructor(path: string, contextBuilder: (scene?: string) => (store: DbStore<ED, Cxt>) => Promise<Cxt>, nsDs: Namespace, nsServer: Namespace, socketPath: string);
14
+ protected registerTrigger(trigger: Trigger<ED, keyof ED, Cxt>): void;
15
+ protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt): Promise<OperationResult<ED>>;
16
+ protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt): Promise<Partial<ED[T]['Schema']>[]>;
17
+ }
@@ -1,142 +1,142 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ClusterAppLoader = void 0;
4
- const tslib_1 = require("tslib");
5
- const lodash_1 = require("oak-domain/lib/utils/lodash");
6
- const filter_1 = require("oak-domain/lib/store/filter");
7
- const env_1 = require("./cluster/env");
8
- const AppLoader_1 = require("./AppLoader");
9
- const assert_1 = tslib_1.__importDefault(require("assert"));
10
- const socket_io_client_1 = require("socket.io-client");
11
- class ClusterAppLoader extends AppLoader_1.AppLoader {
12
- socket;
13
- csTriggers;
14
- connect() {
15
- const { instanceId } = (0, env_1.getClusterInfo)();
16
- this.socket.on('connect', () => {
17
- const csTriggerNames = Object.keys(this.csTriggers).map(ele => `${ele}-${instanceId}`);
18
- if (csTriggerNames.length > 0) {
19
- this.socket.emit('sub', csTriggerNames);
20
- }
21
- });
22
- this.socket.on('disconnect', () => {
23
- const csTriggerNames = Object.keys(this.csTriggers).map(ele => `${ele}-${instanceId}`);
24
- if (csTriggerNames.length > 0) {
25
- this.socket.connect();
26
- }
27
- });
28
- this.socket.on('data', async (entity, name, ids, cxtStr, option) => {
29
- const context = await this.makeContext(cxtStr);
30
- await context.begin();
31
- try {
32
- await this.dbStore.execVolatileTrigger(entity, name, ids, context, option);
33
- await context.commit();
34
- }
35
- catch (err) {
36
- await context.rollback();
37
- console.error('在集群环境下,处理来自其它实例的trigger数据,execVolatileTrigger异常', entity, name, ids, option, err);
38
- }
39
- });
40
- this.socket.connect();
41
- }
42
- sub(name) {
43
- const { instanceId } = (0, env_1.getClusterInfo)();
44
- (0, assert_1.default)(!this.csTriggers[name], `命名为${name}的trigger出现了多次,请检查`);
45
- this.csTriggers[name] = 1;
46
- if (this.socket.connected) {
47
- this.socket.emit('sub', [`${name}-${instanceId}`]);
48
- }
49
- else {
50
- this.socket.connect();
51
- }
52
- }
53
- constructor(path, contextBuilder, nsDs, nsServer, socketPath) {
54
- super(path, contextBuilder, nsDs, nsServer);
55
- this.dbStore.setOnVolatileTrigger(async (entity, trigger, ids, cxtStr, option) => {
56
- const execLocal = async (ids2) => {
57
- const context = await this.makeContext(cxtStr);
58
- await context.begin();
59
- try {
60
- await this.dbStore.execVolatileTrigger(entity, trigger.name, ids2, context, option);
61
- await context.commit();
62
- }
63
- catch (err) {
64
- await context.rollback();
65
- console.error('execVolatileTrigger异常', entity, trigger.name, ids2, option, err);
66
- }
67
- };
68
- if (trigger.cs) {
69
- // 如果是cluster sensative的触发器,需要发送到相应的instance上被处理
70
- const context = await this.makeContext();
71
- const rows = await context.select(entity, {
72
- data: {
73
- id: 1,
74
- $$seq$$: 1,
75
- },
76
- filter: {
77
- id: { $in: ids },
78
- }
79
- }, { dontCollect: true });
80
- await context.commit();
81
- const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
82
- const grouped = (0, lodash_1.groupBy)(rows, (ele) => ele.$$seq$$ % instanceCount);
83
- for (const seqMod in grouped) {
84
- const ids2 = grouped[seqMod].map(ele => ele.id);
85
- if (parseInt(seqMod) === instanceId) {
86
- await execLocal(ids2);
87
- }
88
- else {
89
- this.dataSubscriber.publishVolatileTrigger(entity, trigger.name, seqMod, ids2, cxtStr, option);
90
- }
91
- }
92
- }
93
- else {
94
- await execLocal(ids);
95
- }
96
- });
97
- const { name } = nsServer;
98
- const socketUrl = `http://localhost:${process.env.PM2_PORT || 8080}${name}`;
99
- this.socket = (0, socket_io_client_1.io)(socketUrl, {
100
- path: socketPath,
101
- });
102
- this.connect();
103
- this.csTriggers = {};
104
- }
105
- registerTrigger(trigger) {
106
- // 如果是cluster sensative的trigger,注册到socket事件上
107
- if (trigger.when === 'commit' && trigger.cs) {
108
- const { name } = trigger;
109
- this.sub(name);
110
- }
111
- this.dbStore.registerTrigger(trigger);
112
- }
113
- operateInWatcher(entity, operation, context) {
114
- const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
115
- (0, assert_1.default)(instanceCount && typeof instanceId === 'number');
116
- const { filter } = operation;
117
- const filter2 = (0, filter_1.combineFilters)(entity, this.dbStore.getSchema(), [filter, {
118
- $$seq$$: {
119
- $mod: [instanceCount, instanceId]
120
- }
121
- }]);
122
- return super.operateInWatcher(entity, {
123
- ...operation,
124
- filter: filter2,
125
- }, context);
126
- }
127
- selectInWatcher(entity, selection, context) {
128
- const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
129
- (0, assert_1.default)(instanceCount && typeof instanceId === 'number');
130
- const { filter } = selection;
131
- const filter2 = (0, filter_1.combineFilters)(entity, this.dbStore.getSchema(), [filter, {
132
- $$seq$$: {
133
- $mod: [instanceCount, instanceId]
134
- }
135
- }]);
136
- return super.selectInWatcher(entity, {
137
- ...selection,
138
- filter: filter2,
139
- }, context);
140
- }
141
- }
142
- exports.ClusterAppLoader = ClusterAppLoader;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClusterAppLoader = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = require("oak-domain/lib/utils/lodash");
6
+ const filter_1 = require("oak-domain/lib/store/filter");
7
+ const env_1 = require("./cluster/env");
8
+ const AppLoader_1 = require("./AppLoader");
9
+ const assert_1 = tslib_1.__importDefault(require("assert"));
10
+ const socket_io_client_1 = require("socket.io-client");
11
+ class ClusterAppLoader extends AppLoader_1.AppLoader {
12
+ socket;
13
+ csTriggers;
14
+ connect() {
15
+ const { instanceId } = (0, env_1.getClusterInfo)();
16
+ this.socket.on('connect', () => {
17
+ const csTriggerNames = Object.keys(this.csTriggers).map(ele => `${ele}-${instanceId}`);
18
+ if (csTriggerNames.length > 0) {
19
+ this.socket.emit('sub', csTriggerNames);
20
+ }
21
+ });
22
+ this.socket.on('disconnect', () => {
23
+ const csTriggerNames = Object.keys(this.csTriggers).map(ele => `${ele}-${instanceId}`);
24
+ if (csTriggerNames.length > 0) {
25
+ this.socket.connect();
26
+ }
27
+ });
28
+ this.socket.on('data', async (entity, name, ids, cxtStr, option) => {
29
+ const context = await this.makeContext(cxtStr);
30
+ await context.begin();
31
+ try {
32
+ await this.dbStore.execVolatileTrigger(entity, name, ids, context, option);
33
+ await context.commit();
34
+ }
35
+ catch (err) {
36
+ await context.rollback();
37
+ console.error('在集群环境下,处理来自其它实例的trigger数据,execVolatileTrigger异常', entity, name, ids, option, err);
38
+ }
39
+ });
40
+ this.socket.connect();
41
+ }
42
+ sub(name) {
43
+ const { instanceId } = (0, env_1.getClusterInfo)();
44
+ (0, assert_1.default)(!this.csTriggers[name], `命名为${name}的trigger出现了多次,请检查`);
45
+ this.csTriggers[name] = 1;
46
+ if (this.socket.connected) {
47
+ this.socket.emit('sub', [`${name}-${instanceId}`]);
48
+ }
49
+ else {
50
+ this.socket.connect();
51
+ }
52
+ }
53
+ constructor(path, contextBuilder, nsDs, nsServer, socketPath) {
54
+ super(path, contextBuilder, nsDs, nsServer);
55
+ this.dbStore.setOnVolatileTrigger(async (entity, trigger, ids, cxtStr, option) => {
56
+ const execLocal = async (ids2) => {
57
+ const context = await this.makeContext(cxtStr);
58
+ await context.begin();
59
+ try {
60
+ await this.dbStore.execVolatileTrigger(entity, trigger.name, ids2, context, option);
61
+ await context.commit();
62
+ }
63
+ catch (err) {
64
+ await context.rollback();
65
+ console.error('execVolatileTrigger异常', entity, trigger.name, ids2, option, err);
66
+ }
67
+ };
68
+ if (trigger.cs) {
69
+ // 如果是cluster sensative的触发器,需要发送到相应的instance上被处理
70
+ const context = await this.makeContext();
71
+ const rows = await context.select(entity, {
72
+ data: {
73
+ id: 1,
74
+ $$seq$$: 1,
75
+ },
76
+ filter: {
77
+ id: { $in: ids },
78
+ }
79
+ }, { dontCollect: true });
80
+ await context.commit();
81
+ const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
82
+ const grouped = (0, lodash_1.groupBy)(rows, (ele) => ele.$$seq$$ % instanceCount);
83
+ for (const seqMod in grouped) {
84
+ const ids2 = grouped[seqMod].map(ele => ele.id);
85
+ if (parseInt(seqMod) === instanceId) {
86
+ await execLocal(ids2);
87
+ }
88
+ else {
89
+ this.dataSubscriber.publishVolatileTrigger(entity, trigger.name, seqMod, ids2, cxtStr, option);
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ await execLocal(ids);
95
+ }
96
+ });
97
+ const { name } = nsServer;
98
+ const socketUrl = `http://localhost:${process.env.PM2_PORT || 8080}${name}`;
99
+ this.socket = (0, socket_io_client_1.io)(socketUrl, {
100
+ path: socketPath,
101
+ });
102
+ this.connect();
103
+ this.csTriggers = {};
104
+ }
105
+ registerTrigger(trigger) {
106
+ // 如果是cluster sensative的trigger,注册到socket事件上
107
+ if (trigger.when === 'commit' && trigger.cs) {
108
+ const { name } = trigger;
109
+ this.sub(name);
110
+ }
111
+ this.dbStore.registerTrigger(trigger);
112
+ }
113
+ operateInWatcher(entity, operation, context) {
114
+ const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
115
+ (0, assert_1.default)(instanceCount && typeof instanceId === 'number');
116
+ const { filter } = operation;
117
+ const filter2 = (0, filter_1.combineFilters)(entity, this.dbStore.getSchema(), [filter, {
118
+ $$seq$$: {
119
+ $mod: [instanceCount, instanceId]
120
+ }
121
+ }]);
122
+ return super.operateInWatcher(entity, {
123
+ ...operation,
124
+ filter: filter2,
125
+ }, context);
126
+ }
127
+ selectInWatcher(entity, selection, context) {
128
+ const { instanceCount, instanceId } = (0, env_1.getClusterInfo)();
129
+ (0, assert_1.default)(instanceCount && typeof instanceId === 'number');
130
+ const { filter } = selection;
131
+ const filter2 = (0, filter_1.combineFilters)(entity, this.dbStore.getSchema(), [filter, {
132
+ $$seq$$: {
133
+ $mod: [instanceCount, instanceId]
134
+ }
135
+ }]);
136
+ return super.selectInWatcher(entity, {
137
+ ...selection,
138
+ filter: filter2,
139
+ }, context);
140
+ }
141
+ }
142
+ exports.ClusterAppLoader = ClusterAppLoader;
@@ -1,18 +1,18 @@
1
- import { EntityDict } from 'oak-domain/lib/types';
2
- import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
3
- import { BackendRuntimeContext } from 'oak-frontend-base';
4
- import { Namespace } from 'socket.io';
5
- export default class DataSubscriber<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
6
- private ns;
7
- private contextBuilder;
8
- private filterMap;
9
- private idEntityMap;
10
- constructor(ns: Namespace, contextBuilder: (scene?: string) => Promise<Context>);
11
- private formCreateRoomRoutine;
12
- /**
13
- * 来自外部的socket连接,监听数据变化
14
- */
15
- private startup;
16
- private sendRecord;
17
- onDataCommited(context: Context): void;
18
- }
1
+ import { EntityDict } from 'oak-domain/lib/types';
2
+ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
3
+ import { BackendRuntimeContext } from 'oak-frontend-base';
4
+ import { Namespace } from 'socket.io';
5
+ export default class DataSubscriber<ED extends EntityDict & BaseEntityDict, Context extends BackendRuntimeContext<ED>> {
6
+ private ns;
7
+ private contextBuilder;
8
+ private filterMap;
9
+ private idEntityMap;
10
+ constructor(ns: Namespace, contextBuilder: (scene?: string) => Promise<Context>);
11
+ private formCreateRoomRoutine;
12
+ /**
13
+ * 来自外部的socket连接,监听数据变化
14
+ */
15
+ private startup;
16
+ private sendRecord;
17
+ onDataCommited(context: Context): void;
18
+ }