glasswork 1.2.0 → 1.3.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/dist/jobs/define-job.d.ts +4 -4
  3. package/dist/jobs/define-job.d.ts.map +1 -1
  4. package/dist/jobs/drivers/mock-driver.d.ts.map +1 -1
  5. package/dist/jobs/drivers/mock-driver.js +11 -1
  6. package/dist/jobs/drivers/mock-driver.js.map +1 -1
  7. package/dist/jobs/index.d.ts +2 -2
  8. package/dist/jobs/index.d.ts.map +1 -1
  9. package/dist/jobs/index.js +1 -1
  10. package/dist/jobs/index.js.map +1 -1
  11. package/dist/jobs/job-service.d.ts +6 -6
  12. package/dist/jobs/job-service.d.ts.map +1 -1
  13. package/dist/jobs/job-service.js +8 -0
  14. package/dist/jobs/job-service.js.map +1 -1
  15. package/dist/jobs/observability/emf.d.ts +5 -15
  16. package/dist/jobs/observability/emf.d.ts.map +1 -1
  17. package/dist/jobs/observability/emf.js +87 -67
  18. package/dist/jobs/observability/emf.js.map +1 -1
  19. package/dist/jobs/observability/index.d.ts +2 -4
  20. package/dist/jobs/observability/index.d.ts.map +1 -1
  21. package/dist/jobs/observability/index.js +1 -3
  22. package/dist/jobs/observability/index.js.map +1 -1
  23. package/dist/jobs/observability/types.d.ts +16 -193
  24. package/dist/jobs/observability/types.d.ts.map +1 -1
  25. package/dist/jobs/types.d.ts +4 -4
  26. package/dist/jobs/types.d.ts.map +1 -1
  27. package/dist/jobs/worker.d.ts +3 -0
  28. package/dist/jobs/worker.d.ts.map +1 -1
  29. package/dist/jobs/worker.js +71 -12
  30. package/dist/jobs/worker.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/jobs/observability/client.d.ts +0 -26
  33. package/dist/jobs/observability/client.d.ts.map +0 -1
  34. package/dist/jobs/observability/client.js +0 -286
  35. package/dist/jobs/observability/client.js.map +0 -1
  36. package/dist/jobs/observability/dashboard.d.ts +0 -19
  37. package/dist/jobs/observability/dashboard.d.ts.map +0 -1
  38. package/dist/jobs/observability/dashboard.js +0 -144
  39. package/dist/jobs/observability/dashboard.js.map +0 -1
  40. package/dist/jobs/scheduler.d.ts +0 -17
  41. package/dist/jobs/scheduler.d.ts.map +0 -1
  42. package/dist/jobs/scheduler.js +0 -83
  43. package/dist/jobs/scheduler.js.map +0 -1
@@ -1,286 +0,0 @@
1
- function createJobMetricStat(namespace, jobName, metricName, id, period, stat) {
2
- return {
3
- Id: id,
4
- MetricStat: {
5
- Metric: {
6
- Namespace: namespace,
7
- MetricName: metricName,
8
- Dimensions: [{ Name: 'JobName', Value: jobName }],
9
- },
10
- Period: period,
11
- Stat: stat,
12
- },
13
- ReturnData: true,
14
- };
15
- }
16
- function buildMetricDataQueries(namespace, periodSeconds, jobNames) {
17
- const queries = [
18
- {
19
- Id: 'm_total',
20
- MetricStat: {
21
- Metric: { Namespace: namespace, MetricName: 'JobCount' },
22
- Period: periodSeconds,
23
- Stat: 'Sum',
24
- },
25
- ReturnData: true,
26
- },
27
- {
28
- Id: 'm_errors',
29
- MetricStat: {
30
- Metric: { Namespace: namespace, MetricName: 'JobErrorCount' },
31
- Period: periodSeconds,
32
- Stat: 'Sum',
33
- },
34
- ReturnData: true,
35
- },
36
- {
37
- Id: 'm_retries',
38
- MetricStat: {
39
- Metric: { Namespace: namespace, MetricName: 'RetryCount' },
40
- Period: periodSeconds,
41
- Stat: 'Sum',
42
- },
43
- ReturnData: true,
44
- },
45
- {
46
- Id: 'm_duration_avg',
47
- MetricStat: {
48
- Metric: { Namespace: namespace, MetricName: 'JobDuration' },
49
- Period: periodSeconds,
50
- Stat: 'Average',
51
- },
52
- ReturnData: true,
53
- },
54
- {
55
- Id: 'm_duration_p95',
56
- MetricStat: {
57
- Metric: { Namespace: namespace, MetricName: 'JobDuration' },
58
- Period: periodSeconds,
59
- Stat: 'p95',
60
- },
61
- ReturnData: true,
62
- },
63
- ];
64
- for (let i = 0; i < jobNames.length; i++) {
65
- const name = jobNames[i];
66
- if (!name)
67
- continue;
68
- queries.push(createJobMetricStat(namespace, name, 'JobCount', `j_${i}_total`, periodSeconds, 'Sum'), createJobMetricStat(namespace, name, 'JobErrorCount', `j_${i}_errors`, periodSeconds, 'Sum'), createJobMetricStat(namespace, name, 'RetryCount', `j_${i}_retries`, periodSeconds, 'Sum'), createJobMetricStat(namespace, name, 'JobDuration', `j_${i}_duration_avg`, periodSeconds, 'Average'), createJobMetricStat(namespace, name, 'JobDuration', `j_${i}_duration_p95`, periodSeconds, 'p95'));
69
- }
70
- return queries;
71
- }
72
- function extractJobTypeStats(resultMap, jobNames) {
73
- const byJob = {};
74
- for (let i = 0; i < jobNames.length; i++) {
75
- const name = jobNames[i];
76
- if (!name)
77
- continue;
78
- const count = resultMap.get(`j_${i}_total`) ?? 0;
79
- const failedCount = resultMap.get(`j_${i}_errors`) ?? 0;
80
- byJob[name] = {
81
- jobName: name,
82
- count,
83
- succeededCount: Math.max(0, count - failedCount),
84
- failedCount,
85
- retryCount: resultMap.get(`j_${i}_retries`) ?? 0,
86
- avgDurationMs: Math.round(resultMap.get(`j_${i}_duration_avg`) ?? 0),
87
- p95DurationMs: Math.round(resultMap.get(`j_${i}_duration_p95`) ?? 0),
88
- };
89
- }
90
- return byJob;
91
- }
92
- function parseMetricResults(metricResults, jobNames) {
93
- const resultMap = new Map();
94
- for (const res of metricResults ?? []) {
95
- const val = res.Values && res.Values.length > 0 ? res.Values.reduce((a, b) => a + b, 0) : 0;
96
- resultMap.set(res.Id, val);
97
- }
98
- const totalExecuted = resultMap.get('m_total') ?? 0;
99
- const totalFailed = resultMap.get('m_errors') ?? 0;
100
- const totalRetried = resultMap.get('m_retries') ?? 0;
101
- const totalSucceeded = Math.max(0, totalExecuted - totalFailed);
102
- const avgDurationMs = Math.round(resultMap.get('m_duration_avg') ?? 0);
103
- const p95DurationMs = Math.round(resultMap.get('m_duration_p95') ?? 0);
104
- const successRate = totalExecuted > 0
105
- ? Math.round(((totalExecuted - totalFailed) / totalExecuted) * 10000) / 100
106
- : 100;
107
- return {
108
- totalExecuted,
109
- totalSucceeded,
110
- totalFailed,
111
- totalRetried,
112
- successRate,
113
- avgDurationMs,
114
- p95DurationMs,
115
- byJob: extractJobTypeStats(resultMap, jobNames),
116
- };
117
- }
118
- async function pollLogsQuery(client, queryId,
119
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic command class constructor
120
- GetQueryResultsClass) {
121
- for (let i = 0; i < 10; i++) {
122
- const res = (await client.send(new GetQueryResultsClass({ queryId })));
123
- if (res.status === 'Complete') {
124
- return res.results ?? [];
125
- }
126
- if (res.status === 'Failed' || res.status === 'Cancelled') {
127
- break;
128
- }
129
- await new Promise((resolve) => setTimeout(resolve, 300));
130
- }
131
- return [];
132
- }
133
- function mapFailedJobRow(row) {
134
- const map = new Map();
135
- for (const cell of row) {
136
- if (cell.field && cell.value) {
137
- map.set(cell.field, cell.value);
138
- }
139
- }
140
- const timestampStr = map.get('@timestamp') ?? new Date().toISOString();
141
- const durationStr = map.get('JobDuration');
142
- const queueWaitStr = map.get('QueueWaitTime');
143
- return {
144
- jobId: map.get('JobId') ?? '',
145
- jobName: map.get('JobName') ?? '',
146
- attemptNumber: Number(map.get('AttemptNumber') ?? '1'),
147
- errorMessage: map.get('ErrorMessage') ?? '',
148
- errorName: map.get('ErrorName'),
149
- errorStack: map.get('ErrorStack'),
150
- failedAt: new Date(timestampStr),
151
- durationMs: durationStr ? Number(durationStr) : undefined,
152
- queueWaitTimeMs: queueWaitStr ? Number(queueWaitStr) : undefined,
153
- };
154
- }
155
- /**
156
- * Create an observability client for querying background job metrics and execution logs.
157
- *
158
- * @param options - Configuration options including namespace, logGroupName, and region.
159
- * @returns A JobsObservabilityClient instance.
160
- */
161
- export function createJobsObservabilityClient(options = {}) {
162
- const { namespace = 'Glasswork/Jobs', logGroupName, region = process.env.AWS_REGION || 'eu-west-1', } = options;
163
- let cwClient = options.cloudWatchClient ?? null;
164
- let cwLogsClient = options.cloudWatchLogsClient ?? null;
165
- async function getCloudWatchClient() {
166
- if (cwClient)
167
- return cwClient;
168
- try {
169
- const sdk = (await import('@aws-sdk/client-cloudwatch'));
170
- const CloudWatchClient = sdk.CloudWatchClient;
171
- cwClient = new CloudWatchClient({ region });
172
- return cwClient;
173
- }
174
- catch {
175
- throw new Error('Package "@aws-sdk/client-cloudwatch" is required to query metrics. Please install it or inject a cloudWatchClient.');
176
- }
177
- }
178
- async function getCloudWatchLogsClient() {
179
- if (cwLogsClient)
180
- return cwLogsClient;
181
- try {
182
- const sdk = (await import('@aws-sdk/client-cloudwatch-logs'));
183
- const CloudWatchLogsClient = sdk.CloudWatchLogsClient;
184
- cwLogsClient = new CloudWatchLogsClient({ region });
185
- return cwLogsClient;
186
- }
187
- catch {
188
- throw new Error('Package "@aws-sdk/client-cloudwatch-logs" is required to query logs. Please install it or inject a cloudWatchLogsClient.');
189
- }
190
- }
191
- return {
192
- async getSummary(queryOptions = {}) {
193
- const client = await getCloudWatchClient();
194
- const hours = queryOptions.hours ?? 24;
195
- const endTime = queryOptions.endTime ?? new Date();
196
- const startTime = queryOptions.startTime ?? new Date(endTime.getTime() - hours * 60 * 60 * 1000);
197
- const period = Math.max(60, Math.floor((endTime.getTime() - startTime.getTime()) / 1000));
198
- const jobNames = queryOptions.jobNames ?? [];
199
- const metricDataQueries = buildMetricDataQueries(namespace, period, jobNames);
200
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic command invocation
201
- let CommandClass;
202
- try {
203
- const sdk = (await import('@aws-sdk/client-cloudwatch'));
204
- CommandClass = sdk.GetMetricDataCommand;
205
- }
206
- catch {
207
- CommandClass = class GetMetricDataCommand {
208
- input;
209
- constructor(input) {
210
- this.input = input;
211
- }
212
- };
213
- }
214
- const response = (await client.send(new CommandClass({
215
- StartTime: startTime,
216
- EndTime: endTime,
217
- MetricDataQueries: metricDataQueries,
218
- })));
219
- return parseMetricResults(response.MetricDataResults, jobNames);
220
- },
221
- async getJobTypeStats(jobName, queryOptions = {}) {
222
- const summary = await this.getSummary({
223
- ...queryOptions,
224
- jobNames: [jobName],
225
- });
226
- return (summary.byJob[jobName] ?? {
227
- jobName,
228
- count: 0,
229
- succeededCount: 0,
230
- failedCount: 0,
231
- retryCount: 0,
232
- avgDurationMs: 0,
233
- p95DurationMs: 0,
234
- });
235
- },
236
- async getFailedJobs(failedOptions = {}) {
237
- if (!logGroupName) {
238
- throw new Error('Option "logGroupName" is required to query failed jobs from CloudWatch Logs.');
239
- }
240
- const client = await getCloudWatchLogsClient();
241
- const limit = failedOptions.limit ?? 25;
242
- const endTime = failedOptions.endTime ?? new Date();
243
- const startTime = failedOptions.startTime ?? new Date(endTime.getTime() - 24 * 60 * 60 * 1000);
244
- const jobNameFilter = failedOptions.jobName ? `and JobName = "${failedOptions.jobName}"` : '';
245
- const queryString = `fields @timestamp, JobName, JobId, AttemptNumber, ErrorName, ErrorMessage, ErrorStack, JobDuration, QueueWaitTime
246
- | filter Status in ["failed", "dead_letter"] ${jobNameFilter}
247
- | sort @timestamp desc
248
- | limit ${limit}`;
249
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic command invocation
250
- let StartQueryCommandClass;
251
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic command invocation
252
- let GetQueryResultsCommandClass;
253
- try {
254
- const sdk = (await import('@aws-sdk/client-cloudwatch-logs'));
255
- StartQueryCommandClass = sdk.StartQueryCommand;
256
- GetQueryResultsCommandClass = sdk.GetQueryResultsCommand;
257
- }
258
- catch {
259
- StartQueryCommandClass = class StartQueryCommand {
260
- input;
261
- constructor(input) {
262
- this.input = input;
263
- }
264
- };
265
- GetQueryResultsCommandClass = class GetQueryResultsCommand {
266
- input;
267
- constructor(input) {
268
- this.input = input;
269
- }
270
- };
271
- }
272
- const startRes = (await client.send(new StartQueryCommandClass({
273
- logGroupName,
274
- startTime: Math.floor(startTime.getTime() / 1000),
275
- endTime: Math.floor(endTime.getTime() / 1000),
276
- queryString,
277
- })));
278
- if (!startRes.queryId) {
279
- return [];
280
- }
281
- const rows = await pollLogsQuery(client, startRes.queryId, GetQueryResultsCommandClass);
282
- return rows.map(mapFailedJobRow);
283
- },
284
- };
285
- }
286
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/jobs/observability/client.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- import type { CloudWatchDashboardDefinition, GenerateJobsDashboardOptions, GetJobsInsightsQueriesOptions, JobsInsightsQueries } from './types.js';
2
- /**
3
- * Generate a production-ready AWS CloudWatch Dashboard JSON definition for background jobs.
4
- *
5
- * Can be deployed via AWS CLI (`aws cloudwatch put-dashboard`), AWS CDK (`CfnDashboard`),
6
- * or Terraform (`aws_cloudwatch_dashboard`).
7
- *
8
- * @param options - Dashboard configuration options (names, widgets, region).
9
- * @returns An object with dashboardName and serialized dashboardBody JSON.
10
- */
11
- export declare function generateJobsDashboard(options: GenerateJobsDashboardOptions): CloudWatchDashboardDefinition;
12
- /**
13
- * Returns a set of pre-canned CloudWatch Logs Insights queries for monitoring and troubleshooting jobs.
14
- *
15
- * @param options - Optional configuration for logGroupName and namespace filter.
16
- * @returns Queries for recent failures, slowest jobs, retries, and job tracing.
17
- */
18
- export declare function getJobsInsightsQueries(options?: GetJobsInsightsQueriesOptions): JobsInsightsQueries;
19
- //# sourceMappingURL=dashboard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/jobs/observability/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,4BAA4B,GACpC,6BAA6B,CAqI/B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,6BAAkC,GAC1C,mBAAmB,CAerB"}
@@ -1,144 +0,0 @@
1
- /**
2
- * Generate a production-ready AWS CloudWatch Dashboard JSON definition for background jobs.
3
- *
4
- * Can be deployed via AWS CLI (`aws cloudwatch put-dashboard`), AWS CDK (`CfnDashboard`),
5
- * or Terraform (`aws_cloudwatch_dashboard`).
6
- *
7
- * @param options - Dashboard configuration options (names, widgets, region).
8
- * @returns An object with dashboardName and serialized dashboardBody JSON.
9
- */
10
- export function generateJobsDashboard(options) {
11
- const { dashboardName, namespace = 'Glasswork/Jobs', jobNames = [], periodSeconds = 300, region = 'eu-west-1', logGroupName, } = options;
12
- // Widget 1: Throughput (JobCount)
13
- const throughputMetrics = jobNames.length > 0
14
- ? jobNames.map((name) => [namespace, 'JobCount', 'JobName', name, { stat: 'Sum' }])
15
- : [[namespace, 'JobCount', { stat: 'Sum' }]];
16
- // Widget 2: Errors (JobErrorCount)
17
- const errorMetrics = jobNames.length > 0
18
- ? jobNames.map((name) => [
19
- namespace,
20
- 'JobErrorCount',
21
- 'JobName',
22
- name,
23
- { stat: 'Sum', color: '#d62728' },
24
- ])
25
- : [[namespace, 'JobErrorCount', { stat: 'Sum', color: '#d62728' }]];
26
- // Widget 3: Duration Percentiles
27
- const durationMetrics = [
28
- [namespace, 'JobDuration', { stat: 'p50', label: 'Duration p50' }],
29
- [namespace, 'JobDuration', { stat: 'p90', label: 'Duration p90' }],
30
- [namespace, 'JobDuration', { stat: 'p99', label: 'Duration p99' }],
31
- ];
32
- // Widget 4: Queue Wait Time
33
- const queueWaitMetrics = [
34
- [namespace, 'QueueWaitTime', { stat: 'Average', label: 'Avg Queue Wait' }],
35
- [namespace, 'QueueWaitTime', { stat: 'Maximum', label: 'Max Queue Wait' }],
36
- ];
37
- // biome-ignore lint/suspicious/noExplicitAny: CloudWatch Dashboard JSON specification uses dynamic property arrays
38
- const widgets = [
39
- {
40
- type: 'metric',
41
- x: 0,
42
- y: 0,
43
- width: 12,
44
- height: 6,
45
- properties: {
46
- metrics: throughputMetrics,
47
- view: 'timeSeries',
48
- stacked: true,
49
- region,
50
- title: 'Background Jobs - Throughput (JobCount)',
51
- period: periodSeconds,
52
- },
53
- },
54
- {
55
- type: 'metric',
56
- x: 12,
57
- y: 0,
58
- width: 12,
59
- height: 6,
60
- properties: {
61
- metrics: errorMetrics,
62
- view: 'timeSeries',
63
- stacked: true,
64
- region,
65
- title: 'Background Jobs - Errors & Failures',
66
- period: periodSeconds,
67
- },
68
- },
69
- {
70
- type: 'metric',
71
- x: 0,
72
- y: 6,
73
- width: 12,
74
- height: 6,
75
- properties: {
76
- metrics: durationMetrics,
77
- view: 'timeSeries',
78
- region,
79
- title: 'Execution Duration (p50 / p90 / p99)',
80
- period: periodSeconds,
81
- yAxis: {
82
- left: {
83
- label: 'Milliseconds',
84
- },
85
- },
86
- },
87
- },
88
- {
89
- type: 'metric',
90
- x: 12,
91
- y: 6,
92
- width: 12,
93
- height: 6,
94
- properties: {
95
- metrics: queueWaitMetrics,
96
- view: 'timeSeries',
97
- region,
98
- title: 'Queue Wait Time (Enqueued to Execution)',
99
- period: periodSeconds,
100
- yAxis: {
101
- left: {
102
- label: 'Milliseconds',
103
- },
104
- },
105
- },
106
- },
107
- ];
108
- if (logGroupName) {
109
- widgets.push({
110
- type: 'log',
111
- x: 0,
112
- y: 12,
113
- width: 24,
114
- height: 6,
115
- properties: {
116
- query: `SOURCE '${logGroupName}' | fields @timestamp, JobName, JobId, AttemptNumber, ErrorName, ErrorMessage\n| filter Status in ["failed", "dead_letter"]\n| sort @timestamp desc\n| limit 25`,
117
- region,
118
- title: 'Recent Job Failures & Dead Letters',
119
- view: 'table',
120
- },
121
- });
122
- }
123
- return {
124
- dashboardName,
125
- dashboardBody: JSON.stringify({ widgets }),
126
- };
127
- }
128
- /**
129
- * Returns a set of pre-canned CloudWatch Logs Insights queries for monitoring and troubleshooting jobs.
130
- *
131
- * @param options - Optional configuration for logGroupName and namespace filter.
132
- * @returns Queries for recent failures, slowest jobs, retries, and job tracing.
133
- */
134
- export function getJobsInsightsQueries(options = {}) {
135
- const sourcePrefix = options.logGroupName ? `SOURCE '${options.logGroupName}' | ` : '';
136
- return {
137
- recentFailures: `${sourcePrefix}fields @timestamp, JobName, JobId, AttemptNumber, ErrorName, ErrorMessage\n| filter Status in ["failed", "dead_letter"]\n| sort @timestamp desc\n| limit 50`,
138
- slowestJobs: `${sourcePrefix}fields @timestamp, JobName, JobId, JobDuration, QueueWaitTime\n| filter Status = "success"\n| sort JobDuration desc\n| limit 25`,
139
- retriedJobs: `${sourcePrefix}fields @timestamp, JobName, JobId, AttemptNumber, Status, ErrorMessage\n| filter AttemptNumber > 1\n| sort @timestamp desc\n| limit 50`,
140
- throughputHourly: `${sourcePrefix}filter ispresent(JobName)\n| stats count(*) as Total, sum(JobErrorCount) as Errors, avg(JobDuration) as AvgDurationMs by bin(1h), JobName`,
141
- traceJob: (jobId) => `${sourcePrefix}fields @timestamp, JobName, Status, AttemptNumber, @message\n| filter JobId = "${jobId}"\n| sort @timestamp asc`,
142
- };
143
- }
144
- //# sourceMappingURL=dashboard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/jobs/observability/dashboard.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import type { Logger } from '../utils/logger.js';
2
- import type { QueueDriver } from './types.js';
3
- export interface SchedulerConfig {
4
- tableName: string;
5
- driver: QueueDriver;
6
- region: string;
7
- endpoint?: string;
8
- logger?: Logger;
9
- }
10
- /**
11
- * Create a scheduler handler that reads due jobs from DynamoDB and enqueues them.
12
- * Intended to be triggered periodically (e.g., every minute via EventBridge).
13
- */
14
- export declare function createSchedulerHandler(config: SchedulerConfig): () => Promise<{
15
- dispatched: number;
16
- }>;
17
- //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/jobs/scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiDD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe;;GA4D7D"}
@@ -1,83 +0,0 @@
1
- import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
2
- import { DeleteCommand, DynamoDBDocumentClient, QueryCommand } from '@aws-sdk/lib-dynamodb';
3
- import { createLogger } from '../utils/logger.js';
4
- /**
5
- * Parse a scheduled item from DynamoDB into a job dispatch payload.
6
- * Returns null if the item is invalid or malformed.
7
- */
8
- function parseScheduledItem(item, logger) {
9
- const jobName = item.jobName;
10
- const jobId = item.sk;
11
- if (!jobName || !jobId) {
12
- logger.warn('Skipping scheduled item with missing required fields', {
13
- hasJobName: !!jobName,
14
- hasJobId: !!jobId,
15
- });
16
- return null;
17
- }
18
- let payload;
19
- try {
20
- payload = item.payload ? JSON.parse(item.payload) : undefined;
21
- }
22
- catch (error) {
23
- logger.error('Failed to parse scheduled job payload', { jobName, jobId, error });
24
- return null;
25
- }
26
- return {
27
- jobName,
28
- jobId,
29
- payload,
30
- queue: item.queue ?? 'default',
31
- };
32
- }
33
- /**
34
- * Create a scheduler handler that reads due jobs from DynamoDB and enqueues them.
35
- * Intended to be triggered periodically (e.g., every minute via EventBridge).
36
- */
37
- export function createSchedulerHandler(config) {
38
- const logger = config.logger ?? createLogger('JobScheduler');
39
- const ddbClient = new DynamoDBClient({
40
- region: config.region,
41
- ...(config.endpoint && { endpoint: config.endpoint }),
42
- });
43
- const docClient = DynamoDBDocumentClient.from(ddbClient);
44
- return async () => {
45
- const partition = `SCHEDULED#${new Date().toISOString().slice(0, 16)}`;
46
- const result = await docClient.send(new QueryCommand({
47
- TableName: config.tableName,
48
- KeyConditionExpression: 'pk = :pk',
49
- ExpressionAttributeValues: { ':pk': partition },
50
- }));
51
- if (!result.Items || result.Items.length === 0) {
52
- return { dispatched: 0 };
53
- }
54
- let dispatched = 0;
55
- for (const item of result.Items) {
56
- const parsed = parseScheduledItem(item, logger);
57
- if (!parsed) {
58
- // Delete malformed items to prevent infinite retries
59
- if (item.sk) {
60
- await docClient.send(new DeleteCommand({
61
- TableName: config.tableName,
62
- Key: { pk: partition, sk: item.sk },
63
- }));
64
- }
65
- continue;
66
- }
67
- await config.driver.enqueue({
68
- jobName: parsed.jobName,
69
- payload: parsed.payload,
70
- queue: parsed.queue,
71
- jobId: parsed.jobId,
72
- });
73
- await docClient.send(new DeleteCommand({
74
- TableName: config.tableName,
75
- Key: { pk: partition, sk: parsed.jobId },
76
- }));
77
- dispatched += 1;
78
- }
79
- logger.info('Dispatched scheduled jobs', { dispatched });
80
- return { dispatched };
81
- };
82
- }
83
- //# sourceMappingURL=scheduler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/jobs/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE5F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA0BlD;;;GAGG;AACH,SAAS,kBAAkB,CAAC,IAAmB,EAAE,MAAc;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;IAEtB,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,sDAAsD,EAAE;YAClE,UAAU,EAAE,CAAC,CAAC,OAAO;YACrB,QAAQ,EAAE,CAAC,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO;QACP,KAAK;QACL,OAAO;QACP,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;KAC/B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAuB;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,YAAY,CAAC,cAAc,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;KACtD,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEzD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,SAAS,GAAG,aAAa,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAEvE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CACjC,IAAI,YAAY,CAAC;YACf,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,sBAAsB,EAAE,UAAU;YAClC,yBAAyB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;SAChD,CAAC,CACH,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAqB,EAAE,MAAM,CAAC,CAAC;YAEjE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,qDAAqD;gBACrD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;oBACZ,MAAM,SAAS,CAAC,IAAI,CAClB,IAAI,aAAa,CAAC;wBAChB,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;qBACpC,CAAC,CACH,CAAC;gBACJ,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;gBAC1B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YAEH,MAAM,SAAS,CAAC,IAAI,CAClB,IAAI,aAAa,CAAC;gBAChB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE;aACzC,CAAC,CACH,CAAC;YAEF,UAAU,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,UAAU,EAAE,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC"}