@yarkivaev/scada 2.3.58 → 2.3.60
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/index.js +2 -1
- package/package.json +1 -1
- package/src/application/plantOperations.js +2 -2
- package/src/application/siteServer.js +14 -5
- package/src/domain/operation/operations.js +5 -2
- package/src/infrastructure/persistence/memory/operations.js +10 -1
- package/src/infrastructure/persistence/pg/operations.js +20 -1
- package/src/infrastructure/sync/operationSyncSink.js +4 -2
package/index.js
CHANGED
|
@@ -20,7 +20,8 @@ export { default as shopWithTimeline } from './src/application/shopWithTimeline.
|
|
|
20
20
|
export { default as plantOperations } from './src/application/plantOperations.js';
|
|
21
21
|
export { default as metricsPlant } from './src/application/metricsPlant.js';
|
|
22
22
|
export { default as plantServer } from './src/application/plantServer.js';
|
|
23
|
-
export { default as siteServer } from './src/application/siteServer.js';
|
|
23
|
+
export { default as siteServer, bindSiteOperations } from './src/application/siteServer.js';
|
|
24
|
+
export { acceptOperationDeliver } from './src/infrastructure/sync/operationSyncIngest.js';
|
|
24
25
|
export { default as foldedMetricsSink } from './src/application/foldedMetricsSink.js';
|
|
25
26
|
export {
|
|
26
27
|
default as siteOperatorCatalog,
|
package/package.json
CHANGED
|
@@ -6,9 +6,9 @@ import pubsub from '../domain/shared/pubsub.js';
|
|
|
6
6
|
*
|
|
7
7
|
* Optional kindSources inject non-PG kinds into listForMachine merges.
|
|
8
8
|
*
|
|
9
|
-
* @param {object} persistence - operations store with upsert, upsertMany, get, remove, listForMachine, latestForMachine
|
|
9
|
+
* @param {object} persistence - operations store with upsert, upsertMany, get, remove, drop, listForMachine, latestForMachine
|
|
10
10
|
* @param {object} [kindSources] - map of kind to { list(machineId, range) }
|
|
11
|
-
* @returns {object} operations with listForMachine, latestForMachine, upsert, upsertMany, get, remove, and stream
|
|
11
|
+
* @returns {object} operations with listForMachine, latestForMachine, upsert, upsertMany, get, remove, drop, and stream
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* const ops = plantOperations(dataAccess.operations, { temp: temperaturePort });
|
|
@@ -55,6 +55,19 @@ function startMqtt(sink, env) {
|
|
|
55
55
|
return pipeline;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Replaces sink persistence with the domain operations port used by plant HTTP and AMQP sync.
|
|
60
|
+
*
|
|
61
|
+
* @param {object} sink - supervisor sink with dataAccess.operations
|
|
62
|
+
* @param {object} [kindSources] - optional non-PG kind sources
|
|
63
|
+
* @returns {object} wrapped operations port
|
|
64
|
+
*/
|
|
65
|
+
export function bindSiteOperations(sink, kindSources) {
|
|
66
|
+
const ops = plantOperations(sink.dataAccess.operations, kindSources);
|
|
67
|
+
sink.dataAccess.operations = ops;
|
|
68
|
+
return ops;
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
function startOperationSync(sink, env) {
|
|
59
72
|
if (env.SINK_DB_PROFILE === 'edge' || !env.AMQP_URL) {
|
|
60
73
|
return undefined;
|
|
@@ -106,11 +119,7 @@ function siteExtraRoutes(catalog, extraRoutes) {
|
|
|
106
119
|
export default async function siteServer(config) {
|
|
107
120
|
const env = config.env || process.env;
|
|
108
121
|
const sink = supervisorSink(env);
|
|
109
|
-
const ops =
|
|
110
|
-
sink.dataAccess.operations,
|
|
111
|
-
config.kindSources || config.operationSources
|
|
112
|
-
);
|
|
113
|
-
sink.dataAccess.operations = ops;
|
|
122
|
+
const ops = bindSiteOperations(sink, config.kindSources || config.operationSources);
|
|
114
123
|
const http = edgeApi(sink.dataAccess, {
|
|
115
124
|
port: sink.apiPort,
|
|
116
125
|
token: sink.apiToken,
|
|
@@ -62,10 +62,10 @@ function writeMany(persistence, bus, items) {
|
|
|
62
62
|
* sorted by occurred_at. Omitted kinds default to injectable source keys.
|
|
63
63
|
* latestForMachine reads only from persistence (single kind).
|
|
64
64
|
*
|
|
65
|
-
* @param {object} persistence - store with upsert, get, remove, listForMachine, latestForMachine
|
|
65
|
+
* @param {object} persistence - store with upsert, get, remove, drop, listForMachine, latestForMachine
|
|
66
66
|
* @param {object} bus - pubsub instance with stream and emit methods
|
|
67
67
|
* @param {object} [kindSources] - map of kind to { list(machineId, range) }
|
|
68
|
-
* @returns {object} operations with listForMachine, latestForMachine, upsert, upsertMany, get, remove, stream
|
|
68
|
+
* @returns {object} operations with listForMachine, latestForMachine, upsert, upsertMany, get, remove, drop, stream
|
|
69
69
|
*
|
|
70
70
|
* @example
|
|
71
71
|
* const ops = operations(store, bus, { temp: temperaturePort });
|
|
@@ -107,6 +107,9 @@ export default function operations(persistence, bus, kindSources) {
|
|
|
107
107
|
return operation;
|
|
108
108
|
});
|
|
109
109
|
},
|
|
110
|
+
drop(machineId, key) {
|
|
111
|
+
return persistence.drop(machineId, key);
|
|
112
|
+
},
|
|
110
113
|
stream: bus.stream
|
|
111
114
|
};
|
|
112
115
|
}
|
|
@@ -99,7 +99,7 @@ function filterLatest(store, machineId, kind, bound) {
|
|
|
99
99
|
* In-memory operations state port for tests and local runs.
|
|
100
100
|
*
|
|
101
101
|
* @param {object} store - shared mutable store with operations array
|
|
102
|
-
* @returns {object} operations port matching operationStatePg shape
|
|
102
|
+
* @returns {object} operations port matching operationStatePg shape including drop
|
|
103
103
|
*/
|
|
104
104
|
export default function operationStateMemory(store) {
|
|
105
105
|
if (!store.operations) {
|
|
@@ -126,6 +126,15 @@ export default function operationStateMemory(store) {
|
|
|
126
126
|
const [row] = store.operations.splice(index, 1);
|
|
127
127
|
return Promise.resolve(row);
|
|
128
128
|
},
|
|
129
|
+
drop(machineId, key) {
|
|
130
|
+
const index = store.operations.findIndex((row) => {
|
|
131
|
+
return row.machine === machineId && row.key === key;
|
|
132
|
+
});
|
|
133
|
+
if (index >= 0) {
|
|
134
|
+
store.operations.splice(index, 1);
|
|
135
|
+
}
|
|
136
|
+
return Promise.resolve();
|
|
137
|
+
},
|
|
129
138
|
listForMachine(machineId, kind, range) {
|
|
130
139
|
return Promise.resolve(filterList(store, machineId, kind, range));
|
|
131
140
|
},
|
|
@@ -120,17 +120,33 @@ async function removeOperation(pool, machineId, key) {
|
|
|
120
120
|
return result.rows[0];
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Deletes an operation when present. Absence is success.
|
|
125
|
+
*
|
|
126
|
+
* @param {object} pool - pg pool
|
|
127
|
+
* @param {string} machineId - machine identifier
|
|
128
|
+
* @param {string} key - operation storage key
|
|
129
|
+
* @returns {Promise<void>}
|
|
130
|
+
*/
|
|
131
|
+
function dropOperation(pool, machineId, key) {
|
|
132
|
+
return pool.query(
|
|
133
|
+
'DELETE FROM operations WHERE machine = $1 AND key = $2',
|
|
134
|
+
[machineId, key]
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
/**
|
|
124
139
|
* PostgreSQL operations persistence port for generic machine operations.
|
|
125
140
|
*
|
|
126
141
|
* @param {object} pool - pg pool
|
|
127
|
-
* @returns {object} operations port with upsert, get, remove, listForMachine, latestForMachine
|
|
142
|
+
* @returns {object} operations port with upsert, get, remove, drop, listForMachine, latestForMachine
|
|
128
143
|
*
|
|
129
144
|
* @example
|
|
130
145
|
* const store = operationStatePg(pool);
|
|
131
146
|
* await store.upsert({ machine: 'm1', key: 'nb-1', kind: 'sample', ... });
|
|
132
147
|
* await store.latestForMachine('m1', 'sample', { to: new Date() });
|
|
133
148
|
* await store.remove('m1', 'nb-1');
|
|
149
|
+
* await store.drop('m1', 'nb-1');
|
|
134
150
|
*/
|
|
135
151
|
export default function operationStatePg(pool) {
|
|
136
152
|
return {
|
|
@@ -143,6 +159,9 @@ export default function operationStatePg(pool) {
|
|
|
143
159
|
remove(machineId, key) {
|
|
144
160
|
return removeOperation(pool, machineId, key);
|
|
145
161
|
},
|
|
162
|
+
drop(machineId, key) {
|
|
163
|
+
return dropOperation(pool, machineId, key);
|
|
164
|
+
},
|
|
146
165
|
listForMachine(machineId, kind, range) {
|
|
147
166
|
return listForMachine(pool, machineId, kind, range);
|
|
148
167
|
},
|
|
@@ -3,7 +3,9 @@ import processingErrorLog from '../ingest/processingErrorLog.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* PostgreSQL sink for generic operation sync records.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Federated deletes call operations.drop, which is idempotent when the row is absent.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} operations - Operations port with upsert(item) and drop(machineId, key)
|
|
7
9
|
* @returns {object} Sink with accept() and remove() methods
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
@@ -26,7 +28,7 @@ export default function operationSyncSink(operations) {
|
|
|
26
28
|
},
|
|
27
29
|
async remove(record) {
|
|
28
30
|
try {
|
|
29
|
-
await operations.
|
|
31
|
+
await operations.drop(record.machine, record.key);
|
|
30
32
|
} catch (error) {
|
|
31
33
|
processingErrorLog('operation_sync_sink', error, {
|
|
32
34
|
machine: record.machine,
|