bunqueue 2.6.39 → 2.6.40
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/dist/infrastructure/cloud/buffer.d.ts +18 -0
- package/dist/infrastructure/cloud/buffer.d.ts.map +1 -0
- package/dist/infrastructure/cloud/buffer.js +30 -0
- package/dist/infrastructure/cloud/buffer.js.map +1 -0
- package/dist/infrastructure/cloud/circuitBreaker.d.ts +20 -0
- package/dist/infrastructure/cloud/circuitBreaker.d.ts.map +1 -0
- package/dist/infrastructure/cloud/circuitBreaker.js +47 -0
- package/dist/infrastructure/cloud/circuitBreaker.js.map +1 -0
- package/dist/infrastructure/cloud/cloudAgent.d.ts +39 -0
- package/dist/infrastructure/cloud/cloudAgent.d.ts.map +1 -0
- package/dist/infrastructure/cloud/cloudAgent.js +156 -0
- package/dist/infrastructure/cloud/cloudAgent.js.map +1 -0
- package/dist/infrastructure/cloud/commandHandler.d.ts +34 -0
- package/dist/infrastructure/cloud/commandHandler.d.ts.map +1 -0
- package/dist/infrastructure/cloud/commandHandler.js +101 -0
- package/dist/infrastructure/cloud/commandHandler.js.map +1 -0
- package/dist/infrastructure/cloud/config.d.ts +8 -0
- package/dist/infrastructure/cloud/config.d.ts.map +1 -0
- package/dist/infrastructure/cloud/config.js +31 -0
- package/dist/infrastructure/cloud/config.js.map +1 -0
- package/dist/infrastructure/cloud/httpSender.d.ts +23 -0
- package/dist/infrastructure/cloud/httpSender.d.ts.map +1 -0
- package/dist/infrastructure/cloud/httpSender.js +100 -0
- package/dist/infrastructure/cloud/httpSender.js.map +1 -0
- package/dist/infrastructure/cloud/index.d.ts +11 -0
- package/dist/infrastructure/cloud/index.d.ts.map +1 -0
- package/dist/infrastructure/cloud/index.js +10 -0
- package/dist/infrastructure/cloud/index.js.map +1 -0
- package/dist/infrastructure/cloud/instanceId.d.ts +7 -0
- package/dist/infrastructure/cloud/instanceId.d.ts.map +1 -0
- package/dist/infrastructure/cloud/instanceId.js +34 -0
- package/dist/infrastructure/cloud/instanceId.js.map +1 -0
- package/dist/infrastructure/cloud/logger.d.ts +5 -0
- package/dist/infrastructure/cloud/logger.d.ts.map +1 -0
- package/dist/infrastructure/cloud/logger.js +6 -0
- package/dist/infrastructure/cloud/logger.js.map +1 -0
- package/dist/infrastructure/cloud/snapshotCollector.d.ts +9 -0
- package/dist/infrastructure/cloud/snapshotCollector.d.ts.map +1 -0
- package/dist/infrastructure/cloud/snapshotCollector.js +213 -0
- package/dist/infrastructure/cloud/snapshotCollector.js.map +1 -0
- package/dist/infrastructure/cloud/types.d.ts +210 -0
- package/dist/infrastructure/cloud/types.d.ts.map +1 -0
- package/dist/infrastructure/cloud/types.js +6 -0
- package/dist/infrastructure/cloud/types.js.map +1 -0
- package/dist/infrastructure/cloud/wsSender.d.ts +31 -0
- package/dist/infrastructure/cloud/wsSender.d.ts.map +1 -0
- package/dist/infrastructure/cloud/wsSender.js +121 -0
- package/dist/infrastructure/cloud/wsSender.js.map +1 -0
- package/dist/main.js +8 -0
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Sender
|
|
3
|
+
* Posts snapshots to the remote dashboard via HTTP with retry and HMAC signing
|
|
4
|
+
*/
|
|
5
|
+
import { CircuitBreaker } from './circuitBreaker';
|
|
6
|
+
import { SnapshotBuffer } from './buffer';
|
|
7
|
+
import { cloudLog } from './logger';
|
|
8
|
+
export class HttpSender {
|
|
9
|
+
config;
|
|
10
|
+
circuitBreaker;
|
|
11
|
+
buffer;
|
|
12
|
+
ingestUrl;
|
|
13
|
+
batchUrl;
|
|
14
|
+
hmacKey = null;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.circuitBreaker = new CircuitBreaker(config.circuitBreakerThreshold, config.circuitBreakerResetMs);
|
|
18
|
+
this.buffer = new SnapshotBuffer(config.bufferSize);
|
|
19
|
+
this.ingestUrl = `${config.url}/api/v1/ingest`;
|
|
20
|
+
this.batchUrl = `${config.url}/api/v1/ingest/batch`;
|
|
21
|
+
}
|
|
22
|
+
/** Send a snapshot. Buffers on failure. */
|
|
23
|
+
async send(snapshot) {
|
|
24
|
+
// Flush buffered snapshots first if any
|
|
25
|
+
if (!this.buffer.isEmpty) {
|
|
26
|
+
await this.flushBuffer();
|
|
27
|
+
}
|
|
28
|
+
if (!this.circuitBreaker.canExecute()) {
|
|
29
|
+
this.buffer.push(snapshot);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
await this.post(this.ingestUrl, snapshot);
|
|
34
|
+
this.circuitBreaker.onSuccess();
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
this.circuitBreaker.onFailure();
|
|
38
|
+
this.buffer.push(snapshot);
|
|
39
|
+
cloudLog.debug('Snapshot buffered', {
|
|
40
|
+
buffered: this.buffer.size,
|
|
41
|
+
circuit: this.circuitBreaker.getState(),
|
|
42
|
+
error: String(err),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Try to send buffered snapshots in batches */
|
|
47
|
+
async flushBuffer() {
|
|
48
|
+
if (!this.circuitBreaker.canExecute())
|
|
49
|
+
return;
|
|
50
|
+
while (!this.buffer.isEmpty) {
|
|
51
|
+
const batch = this.buffer.drain(50);
|
|
52
|
+
if (batch.length === 0)
|
|
53
|
+
break;
|
|
54
|
+
try {
|
|
55
|
+
await this.post(this.batchUrl, batch);
|
|
56
|
+
this.circuitBreaker.onSuccess();
|
|
57
|
+
cloudLog.debug('Buffer flushed', { sent: batch.length, remaining: this.buffer.size });
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Put items back (they'll be at the front, order is acceptable)
|
|
61
|
+
for (let i = batch.length - 1; i >= 0; i--) {
|
|
62
|
+
this.buffer.push(batch[i]);
|
|
63
|
+
}
|
|
64
|
+
this.circuitBreaker.onFailure();
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** HTTP POST with auth headers and optional HMAC */
|
|
70
|
+
async post(url, body) {
|
|
71
|
+
const json = JSON.stringify(body);
|
|
72
|
+
const headers = {
|
|
73
|
+
'Content-Type': 'application/json',
|
|
74
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
75
|
+
'X-Timestamp': String(Date.now()),
|
|
76
|
+
};
|
|
77
|
+
if (this.config.signingSecret) {
|
|
78
|
+
this.hmacKey ??= await crypto.subtle.importKey('raw', new TextEncoder().encode(this.config.signingSecret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
79
|
+
const sig = await crypto.subtle.sign('HMAC', this.hmacKey, new TextEncoder().encode(json));
|
|
80
|
+
headers['X-Signature'] = Buffer.from(sig).toString('hex');
|
|
81
|
+
}
|
|
82
|
+
const res = await fetch(url, {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers,
|
|
85
|
+
body: json,
|
|
86
|
+
signal: AbortSignal.timeout(10_000),
|
|
87
|
+
});
|
|
88
|
+
if (!res.ok) {
|
|
89
|
+
const text = await res.text().catch(() => '');
|
|
90
|
+
throw new Error(`HTTP ${res.status}: ${text.slice(0, 200)}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
getBufferSize() {
|
|
94
|
+
return this.buffer.size;
|
|
95
|
+
}
|
|
96
|
+
getCircuitState() {
|
|
97
|
+
return this.circuitBreaker.getState();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=httpSender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpSender.js","sourceRoot":"","sources":["../../../src/infrastructure/cloud/httpSender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bunqueue Cloud - Remote dashboard telemetry agent
|
|
3
|
+
*
|
|
4
|
+
* Sends periodic snapshots and real-time events to bunqueue Cloud (bunqueue.io).
|
|
5
|
+
* Enabled by setting BUNQUEUE_CLOUD_URL and BUNQUEUE_CLOUD_API_KEY env vars.
|
|
6
|
+
* Zero overhead when disabled.
|
|
7
|
+
*/
|
|
8
|
+
export { CloudAgent } from './cloudAgent';
|
|
9
|
+
export { loadCloudConfig } from './config';
|
|
10
|
+
export type { CloudConfig, CloudSnapshot, CloudEvent } from './types';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/cloud/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bunqueue Cloud - Remote dashboard telemetry agent
|
|
3
|
+
*
|
|
4
|
+
* Sends periodic snapshots and real-time events to bunqueue Cloud (bunqueue.io).
|
|
5
|
+
* Enabled by setting BUNQUEUE_CLOUD_URL and BUNQUEUE_CLOUD_API_KEY env vars.
|
|
6
|
+
* Zero overhead when disabled.
|
|
7
|
+
*/
|
|
8
|
+
export { CloudAgent } from './cloudAgent';
|
|
9
|
+
export { loadCloudConfig } from './config';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/cloud/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instanceId.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/cloud/instanceId.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAyB7D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instance ID Manager
|
|
3
|
+
* Generates and persists a unique instance ID to disk
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
const INSTANCE_ID_FILE = 'cloud-instance-id';
|
|
8
|
+
/** Load or generate a persistent instance ID */
|
|
9
|
+
export function getInstanceId(dataPath) {
|
|
10
|
+
if (!dataPath)
|
|
11
|
+
return crypto.randomUUID();
|
|
12
|
+
const dir = dirname(dataPath);
|
|
13
|
+
const filePath = join(dir, INSTANCE_ID_FILE);
|
|
14
|
+
try {
|
|
15
|
+
if (existsSync(filePath)) {
|
|
16
|
+
const id = readFileSync(filePath, 'utf-8').trim();
|
|
17
|
+
if (id.length > 0)
|
|
18
|
+
return id;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Fall through to generate new ID
|
|
23
|
+
}
|
|
24
|
+
const id = crypto.randomUUID();
|
|
25
|
+
try {
|
|
26
|
+
mkdirSync(dir, { recursive: true });
|
|
27
|
+
writeFileSync(filePath, id, 'utf-8');
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Non-fatal: use ephemeral ID if we can't persist
|
|
31
|
+
}
|
|
32
|
+
return id;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=instanceId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instanceId.js","sourceRoot":"","sources":["../../../src/infrastructure/cloud/instanceId.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,gDAAgD;AAChD,MAAM,UAAU,aAAa,CAAC,QAAuB;IACnD,IAAI,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAE1C,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/cloud/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,QAAQ,sCAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/infrastructure/cloud/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot Collector
|
|
3
|
+
* Gathers telemetry data from all bunqueue managers into a single snapshot
|
|
4
|
+
*/
|
|
5
|
+
import type { QueueManager } from '../../application/queueManager';
|
|
6
|
+
import type { CloudSnapshot } from './types';
|
|
7
|
+
/** Collect a full snapshot from all managers. O(SHARD_COUNT) total. */
|
|
8
|
+
export declare function collectSnapshot(queueManager: QueueManager, instanceId: string, instanceName: string, startedAt: number, sequenceId: number): CloudSnapshot;
|
|
9
|
+
//# sourceMappingURL=snapshotCollector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotCollector.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/cloud/snapshotCollector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAKnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,uEAAuE;AACvE,wBAAgB,eAAe,CAC7B,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,aAAa,CA2Hf"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot Collector
|
|
3
|
+
* Gathers telemetry data from all bunqueue managers into a single snapshot
|
|
4
|
+
*/
|
|
5
|
+
import { hostname } from 'os';
|
|
6
|
+
import { throughputTracker } from '../../application/throughputTracker';
|
|
7
|
+
import { latencyTracker } from '../../application/latencyTracker';
|
|
8
|
+
import { getTaskErrorStats } from '../../application/backgroundTasks';
|
|
9
|
+
import { VERSION } from '../../shared/version';
|
|
10
|
+
/** Cached hostname — computed once */
|
|
11
|
+
const HOST = hostname();
|
|
12
|
+
/** Collect a full snapshot from all managers. O(SHARD_COUNT) total. */
|
|
13
|
+
export function collectSnapshot(queueManager, instanceId, instanceName, startedAt, sequenceId) {
|
|
14
|
+
const stats = queueManager.getStats();
|
|
15
|
+
const memStats = queueManager.getMemoryStats();
|
|
16
|
+
const workerStats = queueManager.workerManager.getStats();
|
|
17
|
+
const rates = throughputTracker.getRates();
|
|
18
|
+
const percentiles = latencyTracker.getPercentiles();
|
|
19
|
+
const averages = latencyTracker.getAverages();
|
|
20
|
+
const storage = queueManager.getStorageStatus();
|
|
21
|
+
const crons = queueManager.listCrons();
|
|
22
|
+
const mem = process.memoryUsage();
|
|
23
|
+
// Per-queue stats (includes DLQ counts)
|
|
24
|
+
const perQueue = queueManager.getPerQueueStats();
|
|
25
|
+
const queuesSummary = queueManager.getQueuesSummary();
|
|
26
|
+
const queueNames = queuesSummary.map((q) => q.name);
|
|
27
|
+
const queues = queuesSummary.map((q) => {
|
|
28
|
+
const pq = perQueue.get(q.name);
|
|
29
|
+
return {
|
|
30
|
+
name: q.name,
|
|
31
|
+
waiting: pq?.waiting ?? q.counts.waiting,
|
|
32
|
+
delayed: pq?.delayed ?? q.counts.delayed,
|
|
33
|
+
active: pq?.active ?? q.counts.active,
|
|
34
|
+
dlq: pq?.dlq ?? 0,
|
|
35
|
+
paused: q.paused,
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
instanceId,
|
|
40
|
+
instanceName,
|
|
41
|
+
version: VERSION,
|
|
42
|
+
hostname: HOST,
|
|
43
|
+
pid: process.pid,
|
|
44
|
+
startedAt,
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
sequenceId,
|
|
47
|
+
stats: {
|
|
48
|
+
waiting: stats.waiting,
|
|
49
|
+
delayed: stats.delayed,
|
|
50
|
+
active: stats.active,
|
|
51
|
+
dlq: stats.dlq,
|
|
52
|
+
completed: stats.completed,
|
|
53
|
+
stalled: memStats.stalledCandidates,
|
|
54
|
+
paused: queuesSummary.filter((q) => q.paused).length,
|
|
55
|
+
totalPushed: String(stats.totalPushed),
|
|
56
|
+
totalPulled: String(stats.totalPulled),
|
|
57
|
+
totalCompleted: String(stats.totalCompleted),
|
|
58
|
+
totalFailed: String(stats.totalFailed),
|
|
59
|
+
uptime: stats.uptime,
|
|
60
|
+
cronJobs: stats.cronJobs,
|
|
61
|
+
cronPending: stats.cronPending,
|
|
62
|
+
},
|
|
63
|
+
throughput: rates,
|
|
64
|
+
latency: {
|
|
65
|
+
averages,
|
|
66
|
+
percentiles,
|
|
67
|
+
},
|
|
68
|
+
memory: {
|
|
69
|
+
heapUsed: Math.round((mem.heapUsed / 1024 / 1024) * 100) / 100,
|
|
70
|
+
heapTotal: Math.round((mem.heapTotal / 1024 / 1024) * 100) / 100,
|
|
71
|
+
rss: Math.round((mem.rss / 1024 / 1024) * 100) / 100,
|
|
72
|
+
external: Math.round((mem.external / 1024 / 1024) * 100) / 100,
|
|
73
|
+
},
|
|
74
|
+
collections: {
|
|
75
|
+
jobIndex: memStats.jobIndex,
|
|
76
|
+
completedJobs: memStats.completedJobs,
|
|
77
|
+
jobResults: memStats.jobResults,
|
|
78
|
+
jobLogs: memStats.jobLogs,
|
|
79
|
+
customIdMap: memStats.customIdMap,
|
|
80
|
+
jobLocks: memStats.jobLocks,
|
|
81
|
+
processingTotal: memStats.processingTotal,
|
|
82
|
+
queuedTotal: memStats.queuedTotal,
|
|
83
|
+
temporalIndexTotal: memStats.temporalIndexTotal,
|
|
84
|
+
delayedHeapTotal: memStats.delayedHeapTotal,
|
|
85
|
+
},
|
|
86
|
+
queues,
|
|
87
|
+
workers: workerStats,
|
|
88
|
+
crons: crons.map((c) => ({
|
|
89
|
+
name: c.name,
|
|
90
|
+
queue: c.queue,
|
|
91
|
+
schedule: c.schedule ?? null,
|
|
92
|
+
nextRun: c.nextRun,
|
|
93
|
+
})),
|
|
94
|
+
storage: {
|
|
95
|
+
diskFull: storage.diskFull,
|
|
96
|
+
error: storage.error,
|
|
97
|
+
},
|
|
98
|
+
taskErrors: getTaskErrorStats(),
|
|
99
|
+
// Recent jobs (last 50 across all queues, lightweight — no job data)
|
|
100
|
+
recentJobs: collectRecentJobs(queueManager, queueNames),
|
|
101
|
+
// DLQ entries (last 50 across all queues)
|
|
102
|
+
dlqEntries: collectDlqEntries(queueManager, queueNames),
|
|
103
|
+
// Worker details
|
|
104
|
+
workerDetails: queueManager.workerManager.list().map((w) => ({
|
|
105
|
+
id: w.id,
|
|
106
|
+
name: w.name,
|
|
107
|
+
queues: w.queues,
|
|
108
|
+
concurrency: w.concurrency,
|
|
109
|
+
hostname: w.hostname,
|
|
110
|
+
pid: w.pid,
|
|
111
|
+
lastSeen: w.lastSeen,
|
|
112
|
+
activeJobs: w.activeJobs,
|
|
113
|
+
processedJobs: w.processedJobs,
|
|
114
|
+
failedJobs: w.failedJobs,
|
|
115
|
+
currentJob: w.currentJob,
|
|
116
|
+
})),
|
|
117
|
+
// Per-queue config
|
|
118
|
+
queueConfigs: collectQueueConfigs(queueManager, queueNames),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Collect recent jobs across queues (max 50, newest first) */
|
|
122
|
+
function collectRecentJobs(queueManager, queueNames) {
|
|
123
|
+
const jobs = [];
|
|
124
|
+
const perQueue = Math.max(1, Math.floor(50 / (queueNames.length || 1)));
|
|
125
|
+
for (const name of queueNames) {
|
|
126
|
+
try {
|
|
127
|
+
const queueJobs = queueManager.getJobs(name, {
|
|
128
|
+
state: ['waiting', 'active', 'delayed'],
|
|
129
|
+
start: 0,
|
|
130
|
+
end: perQueue - 1,
|
|
131
|
+
});
|
|
132
|
+
for (const j of queueJobs) {
|
|
133
|
+
const data = j.data;
|
|
134
|
+
const jobName = data?.name ?? 'default';
|
|
135
|
+
const state = j.completedAt
|
|
136
|
+
? 'completed'
|
|
137
|
+
: j.startedAt
|
|
138
|
+
? 'active'
|
|
139
|
+
: j.runAt > Date.now()
|
|
140
|
+
? 'delayed'
|
|
141
|
+
: 'waiting';
|
|
142
|
+
const duration = j.completedAt && j.startedAt ? j.completedAt - j.startedAt : undefined;
|
|
143
|
+
jobs.push({
|
|
144
|
+
id: String(j.id),
|
|
145
|
+
name: jobName,
|
|
146
|
+
queue: j.queue,
|
|
147
|
+
state,
|
|
148
|
+
data,
|
|
149
|
+
priority: j.priority,
|
|
150
|
+
createdAt: j.createdAt,
|
|
151
|
+
startedAt: j.startedAt ?? undefined,
|
|
152
|
+
completedAt: j.completedAt ?? undefined,
|
|
153
|
+
failedReason: state === 'active' && j.attempts > 0
|
|
154
|
+
? `Retry ${j.attempts}/${j.maxAttempts}`
|
|
155
|
+
: undefined,
|
|
156
|
+
attempts: j.attempts,
|
|
157
|
+
maxAttempts: j.maxAttempts,
|
|
158
|
+
duration,
|
|
159
|
+
progress: j.progress > 0 ? j.progress : undefined,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Skip queue on error
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Sort by createdAt desc, limit 50
|
|
168
|
+
return jobs.sort((a, b) => b.createdAt - a.createdAt).slice(0, 50);
|
|
169
|
+
}
|
|
170
|
+
/** Collect DLQ entries across queues (max 50) */
|
|
171
|
+
function collectDlqEntries(queueManager, queueNames) {
|
|
172
|
+
const entries = [];
|
|
173
|
+
for (const name of queueNames) {
|
|
174
|
+
try {
|
|
175
|
+
const dlq = queueManager.getDlqEntries(name);
|
|
176
|
+
for (const e of dlq.slice(0, 20)) {
|
|
177
|
+
entries.push({
|
|
178
|
+
jobId: String(e.job.id),
|
|
179
|
+
queue: e.job.queue,
|
|
180
|
+
reason: e.reason,
|
|
181
|
+
error: e.error,
|
|
182
|
+
enteredAt: e.enteredAt,
|
|
183
|
+
retryCount: e.retryCount,
|
|
184
|
+
attempts: e.job.attempts,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Skip queue on error
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return entries.sort((a, b) => b.enteredAt - a.enteredAt).slice(0, 50);
|
|
193
|
+
}
|
|
194
|
+
/** Collect per-queue config */
|
|
195
|
+
function collectQueueConfigs(queueManager, queueNames) {
|
|
196
|
+
const configs = {};
|
|
197
|
+
for (const name of queueNames) {
|
|
198
|
+
try {
|
|
199
|
+
const stall = queueManager.getStallConfig(name);
|
|
200
|
+
const dlq = queueManager.getDlqConfig(name);
|
|
201
|
+
configs[name] = {
|
|
202
|
+
paused: queueManager.isPaused(name),
|
|
203
|
+
stallConfig: { stallInterval: stall.stallInterval, maxStalls: stall.maxStalls },
|
|
204
|
+
dlqConfig: { maxRetries: dlq.maxAutoRetries, maxAge: dlq.maxAge ?? 0 },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Skip on error
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return configs;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=snapshotCollector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotCollector.js","sourceRoot":"","sources":["../../../src/infrastructure/cloud/snapshotCollector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bunqueue Cloud Types
|
|
3
|
+
* Interfaces for the Cloud agent that sends telemetry to the remote dashboard
|
|
4
|
+
*/
|
|
5
|
+
/** Cloud configuration from environment variables */
|
|
6
|
+
export interface CloudConfig {
|
|
7
|
+
/** Remote dashboard URL (e.g. https://bunqueue.io) */
|
|
8
|
+
readonly url: string;
|
|
9
|
+
/** API key for authentication */
|
|
10
|
+
readonly apiKey: string;
|
|
11
|
+
/** HMAC signing secret (optional) */
|
|
12
|
+
readonly signingSecret: string | null;
|
|
13
|
+
/** Human-readable instance name */
|
|
14
|
+
readonly instanceName: string;
|
|
15
|
+
/** Snapshot interval in ms (default: 5000) */
|
|
16
|
+
readonly intervalMs: number;
|
|
17
|
+
/** Include job data in events (default: false) */
|
|
18
|
+
readonly includeJobData: boolean;
|
|
19
|
+
/** Fields to redact from job data */
|
|
20
|
+
readonly redactFields: string[];
|
|
21
|
+
/** Event types to forward (empty = all) */
|
|
22
|
+
readonly eventFilter: string[];
|
|
23
|
+
/** Max snapshots in offline buffer (default: 720) */
|
|
24
|
+
readonly bufferSize: number;
|
|
25
|
+
/** Circuit breaker: failures before OPEN (default: 5) */
|
|
26
|
+
readonly circuitBreakerThreshold: number;
|
|
27
|
+
/** Circuit breaker: ms in OPEN before HALF_OPEN (default: 60000) */
|
|
28
|
+
readonly circuitBreakerResetMs: number;
|
|
29
|
+
/** Enable WebSocket event stream (default: true) */
|
|
30
|
+
readonly useWebSocket: boolean;
|
|
31
|
+
/** Enable HTTP snapshot posting (default: true) */
|
|
32
|
+
readonly useHttp: boolean;
|
|
33
|
+
/** Data directory for persisting instance ID */
|
|
34
|
+
readonly dataPath: string | null;
|
|
35
|
+
/** Enable remote commands from dashboard (default: false) */
|
|
36
|
+
readonly remoteCommands: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** Snapshot payload sent every N seconds via HTTP POST */
|
|
39
|
+
export interface CloudSnapshot {
|
|
40
|
+
instanceId: string;
|
|
41
|
+
instanceName: string;
|
|
42
|
+
version: string;
|
|
43
|
+
hostname: string;
|
|
44
|
+
pid: number;
|
|
45
|
+
startedAt: number;
|
|
46
|
+
timestamp: number;
|
|
47
|
+
sequenceId: number;
|
|
48
|
+
shutdown?: boolean;
|
|
49
|
+
stats: {
|
|
50
|
+
waiting: number;
|
|
51
|
+
delayed: number;
|
|
52
|
+
active: number;
|
|
53
|
+
dlq: number;
|
|
54
|
+
completed: number;
|
|
55
|
+
totalPushed: string;
|
|
56
|
+
totalPulled: string;
|
|
57
|
+
totalCompleted: string;
|
|
58
|
+
totalFailed: string;
|
|
59
|
+
stalled: number;
|
|
60
|
+
paused: number;
|
|
61
|
+
uptime: number;
|
|
62
|
+
cronJobs: number;
|
|
63
|
+
cronPending: number;
|
|
64
|
+
};
|
|
65
|
+
throughput: {
|
|
66
|
+
pushPerSec: number;
|
|
67
|
+
pullPerSec: number;
|
|
68
|
+
completePerSec: number;
|
|
69
|
+
failPerSec: number;
|
|
70
|
+
};
|
|
71
|
+
latency: {
|
|
72
|
+
averages: {
|
|
73
|
+
pushMs: number;
|
|
74
|
+
pullMs: number;
|
|
75
|
+
ackMs: number;
|
|
76
|
+
};
|
|
77
|
+
percentiles: {
|
|
78
|
+
push: {
|
|
79
|
+
p50: number;
|
|
80
|
+
p95: number;
|
|
81
|
+
p99: number;
|
|
82
|
+
};
|
|
83
|
+
pull: {
|
|
84
|
+
p50: number;
|
|
85
|
+
p95: number;
|
|
86
|
+
p99: number;
|
|
87
|
+
};
|
|
88
|
+
ack: {
|
|
89
|
+
p50: number;
|
|
90
|
+
p95: number;
|
|
91
|
+
p99: number;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
memory: {
|
|
96
|
+
heapUsed: number;
|
|
97
|
+
heapTotal: number;
|
|
98
|
+
rss: number;
|
|
99
|
+
external: number;
|
|
100
|
+
};
|
|
101
|
+
collections: {
|
|
102
|
+
jobIndex: number;
|
|
103
|
+
completedJobs: number;
|
|
104
|
+
jobResults: number;
|
|
105
|
+
jobLogs: number;
|
|
106
|
+
customIdMap: number;
|
|
107
|
+
jobLocks: number;
|
|
108
|
+
processingTotal: number;
|
|
109
|
+
queuedTotal: number;
|
|
110
|
+
temporalIndexTotal: number;
|
|
111
|
+
delayedHeapTotal: number;
|
|
112
|
+
};
|
|
113
|
+
queues: Array<{
|
|
114
|
+
name: string;
|
|
115
|
+
waiting: number;
|
|
116
|
+
delayed: number;
|
|
117
|
+
active: number;
|
|
118
|
+
dlq: number;
|
|
119
|
+
paused: boolean;
|
|
120
|
+
}>;
|
|
121
|
+
workers: {
|
|
122
|
+
total: number;
|
|
123
|
+
active: number;
|
|
124
|
+
totalProcessed: number;
|
|
125
|
+
totalFailed: number;
|
|
126
|
+
activeJobs: number;
|
|
127
|
+
};
|
|
128
|
+
crons: Array<{
|
|
129
|
+
name: string;
|
|
130
|
+
queue: string;
|
|
131
|
+
schedule: string | null;
|
|
132
|
+
nextRun: number;
|
|
133
|
+
}>;
|
|
134
|
+
storage: {
|
|
135
|
+
diskFull: boolean;
|
|
136
|
+
error: string | null;
|
|
137
|
+
};
|
|
138
|
+
taskErrors: Record<string, {
|
|
139
|
+
consecutiveFailures: number;
|
|
140
|
+
lastError?: string;
|
|
141
|
+
lastFailureAt?: number;
|
|
142
|
+
}>;
|
|
143
|
+
/** Recent jobs across all queues (last ~50, newest first) */
|
|
144
|
+
recentJobs: Array<{
|
|
145
|
+
id: string;
|
|
146
|
+
name: string;
|
|
147
|
+
queue: string;
|
|
148
|
+
state: string;
|
|
149
|
+
data?: unknown;
|
|
150
|
+
priority: number;
|
|
151
|
+
createdAt: number;
|
|
152
|
+
startedAt?: number;
|
|
153
|
+
completedAt?: number;
|
|
154
|
+
failedReason?: string;
|
|
155
|
+
attempts: number;
|
|
156
|
+
maxAttempts: number;
|
|
157
|
+
duration?: number;
|
|
158
|
+
progress?: number;
|
|
159
|
+
}>;
|
|
160
|
+
/** DLQ entries across all queues (last ~50) */
|
|
161
|
+
dlqEntries: Array<{
|
|
162
|
+
jobId: string;
|
|
163
|
+
queue: string;
|
|
164
|
+
reason: string;
|
|
165
|
+
error: string | null;
|
|
166
|
+
enteredAt: number;
|
|
167
|
+
retryCount: number;
|
|
168
|
+
attempts: number;
|
|
169
|
+
}>;
|
|
170
|
+
/** Individual worker details */
|
|
171
|
+
workerDetails: Array<{
|
|
172
|
+
id: string;
|
|
173
|
+
name: string;
|
|
174
|
+
queues: string[];
|
|
175
|
+
concurrency: number;
|
|
176
|
+
hostname: string;
|
|
177
|
+
pid: number;
|
|
178
|
+
lastSeen: number;
|
|
179
|
+
activeJobs: number;
|
|
180
|
+
processedJobs: number;
|
|
181
|
+
failedJobs: number;
|
|
182
|
+
currentJob: string | null;
|
|
183
|
+
}>;
|
|
184
|
+
/** Per-queue configuration */
|
|
185
|
+
queueConfigs: Record<string, {
|
|
186
|
+
paused: boolean;
|
|
187
|
+
stallConfig?: {
|
|
188
|
+
stallInterval: number;
|
|
189
|
+
maxStalls: number;
|
|
190
|
+
};
|
|
191
|
+
dlqConfig?: {
|
|
192
|
+
maxRetries: number;
|
|
193
|
+
maxAge: number;
|
|
194
|
+
};
|
|
195
|
+
}>;
|
|
196
|
+
}
|
|
197
|
+
/** Event payload forwarded via WebSocket */
|
|
198
|
+
export interface CloudEvent {
|
|
199
|
+
instanceId: string;
|
|
200
|
+
timestamp: number;
|
|
201
|
+
jobEvent?: {
|
|
202
|
+
eventType: string;
|
|
203
|
+
queue: string;
|
|
204
|
+
jobId: string;
|
|
205
|
+
error?: string;
|
|
206
|
+
progress?: number;
|
|
207
|
+
data?: unknown;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=types.d.ts.map
|