@yarkivaev/scada 2.3.78 → 2.3.79

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yarkivaev/scada",
3
- "version": "2.3.78",
3
+ "version": "2.3.79",
4
4
  "description": "SCADA domain objects, state persistence, and plant monitoring",
5
5
  "repository": {
6
6
  "type": "git",
@@ -6,6 +6,7 @@ import segmentDispatch from '../../../domain/segment/dispatch.js';
6
6
  import segmentCoalesce from '../../../domain/segment/segmentCoalesce.js';
7
7
  import silenceBudget from '../../../domain/segment/silenceBudget.js';
8
8
  import segmentCodec from '../codecs/segmentCodec.js';
9
+ import processingErrorLog from '../processingErrorLog.js';
9
10
  import silentOpenWatch from '../silentOpenWatch.js';
10
11
  import abutSegments from '../sinks/abutSegments.js';
11
12
  import closeOrphanOpen from '../sinks/closeOrphanOpen.js';
@@ -75,7 +76,10 @@ export default function segmentPipeline(stomp, postgres, pool, config) {
75
76
  return {
76
77
  destination,
77
78
  async start() {
78
- await abutSegments(pool, budget);
79
+ const repair = abutSegments(pool, budget);
80
+ void repair.catch((error) => {
81
+ processingErrorLog('abut_segments', error, { budgetSeconds: budget });
82
+ });
79
83
  source.start();
80
84
  await silence.start();
81
85
  },
@@ -18,14 +18,27 @@ export default function silentOpenWatch(closer, budget, options) {
18
18
  throw new Error(`Budget must be a positive number: ${budget}`);
19
19
  }
20
20
  const intervalMs = options && options.intervalMs ? options.intervalMs : 5000;
21
+ const gate = { busy: false };
21
22
  let timer;
22
23
  let active = false;
24
+ function claim() {
25
+ const free = !gate.busy;
26
+ gate.busy = true;
27
+ return free;
28
+ }
29
+ function release() {
30
+ gate.busy = false;
31
+ }
23
32
  async function tick() {
33
+ if (!claim()) {
34
+ return;
35
+ }
24
36
  try {
25
37
  await closer.close(budget);
26
38
  } catch {
27
39
  /* next tick retries */
28
40
  }
41
+ release();
29
42
  }
30
43
  return {
31
44
  async start() {
@@ -15,20 +15,19 @@ export default async function abutSegments(pool, budgetSeconds) {
15
15
  `UPDATE segments AS left_row
16
16
  SET end_time = right_row.start_time,
17
17
  duration = EXTRACT(EPOCH FROM (right_row.start_time - left_row.start_time))
18
- FROM segments AS right_row
19
- WHERE left_row.machine = right_row.machine
20
- AND left_row.kind = right_row.kind
18
+ FROM LATERAL (
19
+ SELECT next.start_time, next.name
20
+ FROM segments AS next
21
+ WHERE next.machine = left_row.machine
22
+ AND next.kind = left_row.kind
23
+ AND next.start_time > left_row.start_time
24
+ ORDER BY next.start_time
25
+ LIMIT 1
26
+ ) AS right_row
27
+ WHERE left_row.duration > 0
21
28
  AND left_row.name = right_row.name
22
- AND left_row.duration > 0
23
29
  AND right_row.start_time > left_row.end_time
24
- AND right_row.start_time - left_row.end_time <= make_interval(secs => $1)
25
- AND right_row.start_time = (
26
- SELECT MIN(next.start_time)
27
- FROM segments AS next
28
- WHERE next.machine = left_row.machine
29
- AND next.kind = left_row.kind
30
- AND next.start_time > left_row.start_time
31
- )`,
30
+ AND right_row.start_time - left_row.end_time <= make_interval(secs => $1)`,
32
31
  [budgetSeconds]
33
32
  );
34
33
  }