@yarkivaev/scada 2.3.82 → 2.3.84
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/README.md
CHANGED
|
@@ -194,6 +194,7 @@ Set `SINK_DB_PROFILE=central|edge`. Migrations run at supervisor-sink startup vi
|
|
|
194
194
|
| `POSTGRES_URL` | Application DB user (`supervisor_sink`) |
|
|
195
195
|
| `POSTGRES_ADMIN_URL` | Admin user for migrations |
|
|
196
196
|
| `SINK_DB_PROFILE` | `central` or `edge` |
|
|
197
|
+
| `SINK_PIPELINES` | `false` skips STOMP segment, decision, and alert consumers. The site container sets this and a `supervisor-sink` container keeps the default |
|
|
197
198
|
| `STATE_HTTP_PORT` / `STATE_HTTP_TOKEN` | Edge internal API |
|
|
198
199
|
| `MQTT_URL`, `MQTT_TOPICS` | Optional metrics ingest |
|
|
199
200
|
| `CLICKHOUSE_URL` | Central metrics sink |
|
package/package.json
CHANGED
|
@@ -15,6 +15,8 @@ const appRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Reads deployment environment into a normalized config object.
|
|
18
|
+
* `SINK_PIPELINES=false` leaves Postgres and the state HTTP API in this process
|
|
19
|
+
* and leaves the STOMP consumers to another container.
|
|
18
20
|
*
|
|
19
21
|
* @param {NodeJS.ProcessEnv} env - process environment
|
|
20
22
|
* @returns {object} deployment configuration
|
|
@@ -35,6 +37,7 @@ export function readDeploymentConfig(env) {
|
|
|
35
37
|
retentionDays: parseInt(env.RETENTION_DAYS || '30', 10),
|
|
36
38
|
migrationsDir: path.join(root, 'db', 'migrations'),
|
|
37
39
|
requestTimeoutMs: parseRequestTimeoutMs(env.REQUEST_TIMEOUT_MS),
|
|
40
|
+
pipelines: env.SINK_PIPELINES !== 'false',
|
|
38
41
|
pipeline: {
|
|
39
42
|
size: parseInt(env.BATCH_SIZE || '50', 10),
|
|
40
43
|
interval: parseInt(env.FLUSH_INTERVAL || '2', 10),
|
|
@@ -87,9 +90,11 @@ export default function supervisorSink(env = process.env) {
|
|
|
87
90
|
} finally {
|
|
88
91
|
await adminPool.end();
|
|
89
92
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
if (cfg.pipelines) {
|
|
94
|
+
await segments.start();
|
|
95
|
+
decisions.start();
|
|
96
|
+
alerts.start();
|
|
97
|
+
}
|
|
93
98
|
if (httpServer) {
|
|
94
99
|
httpServer.start();
|
|
95
100
|
}
|
|
@@ -17,7 +17,7 @@ export default function segmentNormalize(parsed) {
|
|
|
17
17
|
const hasOpts = Array.isArray(parsed.options) && parsed.options.length > 0;
|
|
18
18
|
const resolved = typeof parsed.resolved === 'boolean' ? parsed.resolved : !hasOpts;
|
|
19
19
|
return {
|
|
20
|
-
type: parsed.type,
|
|
20
|
+
type: parsed.type || 'segment',
|
|
21
21
|
machine: parsed.machine,
|
|
22
22
|
name: parsed.name,
|
|
23
23
|
kind: typeof parsed.kind === 'string' && parsed.kind.length > 0 ? parsed.kind : 'phase',
|
|
@@ -153,6 +153,8 @@ export default function segmentCoalesce(codec, options = {}) {
|
|
|
153
153
|
const ctx = { api, lane, codec, size, intervalMs };
|
|
154
154
|
lane.queue = lane.queue.then(() => {
|
|
155
155
|
return step(ctx, envelope, parsed);
|
|
156
|
+
}).catch(() => {
|
|
157
|
+
return undefined;
|
|
156
158
|
});
|
|
157
159
|
return lane.queue;
|
|
158
160
|
},
|
|
@@ -13,21 +13,21 @@
|
|
|
13
13
|
export default async function abutSegments(pool, budgetSeconds) {
|
|
14
14
|
await pool.query(
|
|
15
15
|
`UPDATE segments AS left_row
|
|
16
|
-
SET end_time =
|
|
17
|
-
duration = EXTRACT(EPOCH FROM (
|
|
18
|
-
FROM
|
|
19
|
-
SELECT
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
AND left_row.name =
|
|
29
|
-
AND
|
|
30
|
-
AND
|
|
16
|
+
SET end_time = next_row.next_start,
|
|
17
|
+
duration = EXTRACT(EPOCH FROM (next_row.next_start - left_row.start_time))
|
|
18
|
+
FROM (
|
|
19
|
+
SELECT machine, kind, start_time,
|
|
20
|
+
lead(start_time) OVER (PARTITION BY machine, kind ORDER BY start_time) AS next_start,
|
|
21
|
+
lead(name) OVER (PARTITION BY machine, kind ORDER BY start_time) AS next_name
|
|
22
|
+
FROM segments
|
|
23
|
+
) AS next_row
|
|
24
|
+
WHERE left_row.machine = next_row.machine
|
|
25
|
+
AND left_row.kind = next_row.kind
|
|
26
|
+
AND left_row.start_time = next_row.start_time
|
|
27
|
+
AND left_row.duration > 0
|
|
28
|
+
AND left_row.name = next_row.next_name
|
|
29
|
+
AND next_row.next_start > left_row.end_time
|
|
30
|
+
AND next_row.next_start - left_row.end_time <= make_interval(secs => $1)`,
|
|
31
31
|
[budgetSeconds]
|
|
32
32
|
);
|
|
33
33
|
}
|