@h3ravel/queue 11.0.13 → 11.1.0-alpha.2

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/index.cjs CHANGED
@@ -1,5 +1,339 @@
1
+ let __h3ravel_support = require("@h3ravel/support");
2
+ let __h3ravel_contracts = require("@h3ravel/contracts");
1
3
  let __h3ravel_core = require("@h3ravel/core");
2
4
 
5
+ //#region src/Events/JobFailed.ts
6
+ var JobFailed = class {
7
+ /**
8
+ * Create a new event instance.
9
+ *
10
+ * @param connectionName The connection name.
11
+ * @param job The job instance.
12
+ * @param exception The exception that caused the job to fail.
13
+ */
14
+ constructor(connectionName, job, exception) {
15
+ this.connectionName = connectionName;
16
+ this.job = job;
17
+ this.exception = exception;
18
+ }
19
+ };
20
+
21
+ //#endregion
22
+ //#region src/Exceptions/ManuallyFailedException.ts
23
+ var ManuallyFailedException = class extends __h3ravel_support.RuntimeException {};
24
+
25
+ //#endregion
26
+ //#region src/Exceptions/MaxAttemptsExceededException.ts
27
+ var MaxAttemptsExceededException = class MaxAttemptsExceededException extends __h3ravel_support.RuntimeException {
28
+ /**
29
+ * The job instance.
30
+ */
31
+ job;
32
+ /**
33
+ * Create a new instance for the job.
34
+ *
35
+ * @param job
36
+ */
37
+ static forJob(job) {
38
+ return (0, __h3ravel_support.tap)(new MaxAttemptsExceededException(job.resolveName() + " has been attempted too many times."), (e) => {
39
+ e.job = job;
40
+ });
41
+ }
42
+ };
43
+
44
+ //#endregion
45
+ //#region src/Exceptions/TimeoutExceededException.ts
46
+ var TimeoutExceededException = class TimeoutExceededException extends MaxAttemptsExceededException {
47
+ /**
48
+ * Create a new instance for the job.
49
+ *
50
+ * @param job
51
+ */
52
+ static forJob(job) {
53
+ return (0, __h3ravel_support.tap)(new TimeoutExceededException(job.resolveName() + " has timed out."), (e) => {
54
+ e.job = job;
55
+ });
56
+ }
57
+ };
58
+
59
+ //#endregion
60
+ //#region src/Jobs/JobName.ts
61
+ var JobName = class {
62
+ /**
63
+ * Parse the given job name into a class / method array.
64
+ *
65
+ * @param job
66
+ */
67
+ static parse(_job) {
68
+ return [{}, ""];
69
+ }
70
+ /**
71
+ * Get the resolved name of the queued job class.
72
+ *
73
+ * @param name
74
+ * @param payload
75
+ */
76
+ static resolve(name, payload) {
77
+ if (!payload.displayName) return payload.displayName;
78
+ return name;
79
+ }
80
+ /**
81
+ * Get the class name for queued job class.
82
+ *
83
+ * @param name
84
+ * @param payload
85
+ */
86
+ static resolveClassName(name, payload) {
87
+ if (typeof payload.data.commandName === "string") return payload.data.commandName;
88
+ return name;
89
+ }
90
+ };
91
+
92
+ //#endregion
93
+ //#region src/Jobs/Job.ts
94
+ var Job = class {
95
+ /**
96
+ * The job handler instance.
97
+ */
98
+ instance;
99
+ /**
100
+ * The IoC container instance.
101
+ */
102
+ container;
103
+ /**
104
+ * Indicates if the job has been deleted.
105
+ */
106
+ deleted = false;
107
+ /**
108
+ * Indicates if the job has been released.
109
+ */
110
+ released = false;
111
+ /**
112
+ * Indicates if the job has failed.
113
+ */
114
+ failed = false;
115
+ /**
116
+ * The name of the connection the job belongs to.
117
+ */
118
+ connectionName;
119
+ /**
120
+ * The name of the queue the job belongs to.
121
+ */
122
+ queue;
123
+ /**
124
+ * Get the UUID of the job.
125
+ *
126
+ * @return string|null
127
+ */
128
+ uuid() {
129
+ return this.payload()["uuid"] ?? null;
130
+ }
131
+ /**
132
+ * Fire the job.
133
+ *
134
+ * @return void
135
+ */
136
+ fire() {
137
+ const payload = this.payload();
138
+ const [instance, method] = JobName.parse(payload["job"]);
139
+ (this.instance = this.resolve(instance))[method](this, payload["data"]);
140
+ }
141
+ /**
142
+ * Delete the job from the queue.
143
+ */
144
+ delete() {
145
+ this.deleted = true;
146
+ }
147
+ /**
148
+ * Determine if the job has been deleted.
149
+ */
150
+ isDeleted() {
151
+ return this.deleted;
152
+ }
153
+ /**
154
+ * Release the job back into the queue after (n) seconds.
155
+ *
156
+ * @param delay
157
+ */
158
+ release(delay = 0) {
159
+ this.released = true;
160
+ }
161
+ /**
162
+ * Determine if the job was released back into the queue.
163
+ *
164
+ * @return bool
165
+ */
166
+ isReleased() {
167
+ return this.released;
168
+ }
169
+ /**
170
+ * Determine if the job has been deleted or released.
171
+ */
172
+ isDeletedOrReleased() {
173
+ return this.isDeleted() || this.isReleased();
174
+ }
175
+ /**
176
+ * Determine if the job has been marked as a failure.
177
+ */
178
+ hasFailed() {
179
+ return this.failed;
180
+ }
181
+ /**
182
+ * Mark the job as "failed".
183
+ */
184
+ markAsFailed() {
185
+ this.failed = true;
186
+ }
187
+ /**
188
+ * Delete the job, call the "failed" method, and raise the failed job event.
189
+ *
190
+ * @param e
191
+ */
192
+ fail(e) {
193
+ this.markAsFailed();
194
+ if (this.isDeleted()) return;
195
+ if (this.shouldRollBackDatabaseTransaction(e)) this.container.make("db").connection(this.container.make("config").get("queue.failed.database")).rollBack(0);
196
+ try {
197
+ this.delete();
198
+ this.failedJob(e);
199
+ } finally {
200
+ this.resolve(__h3ravel_contracts.IDispatcher).dispatch(new JobFailed(this.connectionName, this, e || new ManuallyFailedException()));
201
+ }
202
+ }
203
+ /**
204
+ * Determine if the current database transaction should be rolled back to level zero.
205
+ *
206
+ * @param e
207
+ */
208
+ shouldRollBackDatabaseTransaction(e) {
209
+ return e instanceof TimeoutExceededException && this.container.make("config").get("queue.failed.database") && ["database", "database-uuids"].includes(this.container.make("config").get("queue.failed.driver")) && this.container.has("db");
210
+ }
211
+ /**
212
+ * Process an exception that caused the job to fail.
213
+ *
214
+ * @param e
215
+ */
216
+ failedJob(e, ..._args) {
217
+ const payload = this.payload();
218
+ const [classInstance] = JobName.parse(payload.job);
219
+ this.instance = this.resolve(classInstance);
220
+ if (typeof this.instance.failed === "function") this.instance.failedJob(payload.data, e, payload.uuid ?? "", this);
221
+ }
222
+ /**
223
+ * Resolve the given class.
224
+ */
225
+ resolve(className) {
226
+ return this.container.make(className);
227
+ }
228
+ /**
229
+ * Get the resolved job handler instance.
230
+ *
231
+ * @return mixed
232
+ */
233
+ getResolvedJob() {
234
+ return this.instance;
235
+ }
236
+ /**
237
+ * Get the decoded body of the job.
238
+ */
239
+ payload() {
240
+ return JSON.parse(this.getRawBody());
241
+ }
242
+ /**
243
+ * Get the number of times to attempt a job.
244
+ *
245
+ * @return int|null
246
+ */
247
+ maxTries() {
248
+ return this.payload()["maxTries"] ?? null;
249
+ }
250
+ /**
251
+ * Get the number of times to attempt a job after an exception.
252
+ *
253
+ * @return int|null
254
+ */
255
+ maxExceptions() {
256
+ return this.payload()["maxExceptions"] ?? null;
257
+ }
258
+ /**
259
+ * Determine if the job should fail when it timeouts.
260
+ *
261
+ * @return bool
262
+ */
263
+ shouldFailOnTimeout() {
264
+ return this.payload()["failOnTimeout"] ?? false;
265
+ }
266
+ /**
267
+ * The number of seconds to wait before retrying a job that encountered an uncaught exception.
268
+ *
269
+ * @return int|int[]|null
270
+ */
271
+ backoff() {
272
+ return this.payload()["backoff"] ?? this.payload()["delay"] ?? null;
273
+ }
274
+ /**
275
+ * Get the number of seconds the job can run.
276
+ *
277
+ * @return int|null
278
+ */
279
+ timeout() {
280
+ return this.payload()["timeout"] ?? null;
281
+ }
282
+ /**
283
+ * Get the timestamp indicating when the job should timeout.
284
+ *
285
+ * @return int|null
286
+ */
287
+ retryUntil() {
288
+ return this.payload()["retryUntil"] ?? null;
289
+ }
290
+ /**
291
+ * Get the name of the queued job class.
292
+ *
293
+ * @return string
294
+ */
295
+ getName() {
296
+ return this.payload()["job"];
297
+ }
298
+ /**
299
+ * Get the resolved display name of the queued job class.
300
+ *
301
+ * Resolves the name of "wrapped" jobs such as class-based handlers.
302
+ */
303
+ resolveName() {
304
+ return JobName.resolve(this.getName(), this.payload());
305
+ }
306
+ /**
307
+ * Get the class of the queued job.
308
+ *
309
+ * Resolves the class of "wrapped" jobs such as class-based handlers.
310
+ *
311
+ * @return string
312
+ */
313
+ resolveQueuedJobClass() {
314
+ return JobName.resolveClassName(this.getName(), this.payload());
315
+ }
316
+ /**
317
+ * Get the name of the connection the job belongs to.
318
+ */
319
+ getConnectionName() {
320
+ return this.connectionName;
321
+ }
322
+ /**
323
+ * Get the name of the queue the job belongs to.
324
+ */
325
+ getQueue() {
326
+ return this.queue;
327
+ }
328
+ /**
329
+ * Get the service container instance.
330
+ */
331
+ getContainer() {
332
+ return this.container;
333
+ }
334
+ };
335
+
336
+ //#endregion
3
337
  //#region src/Providers/QueueServiceProvider.ts
4
338
  /**
5
339
  * Queues and workers.
@@ -16,4 +350,10 @@ var QueueServiceProvider = class extends __h3ravel_core.ServiceProvider {
16
350
  };
17
351
 
18
352
  //#endregion
19
- exports.QueueServiceProvider = QueueServiceProvider;
353
+ exports.Job = Job;
354
+ exports.JobFailed = JobFailed;
355
+ exports.JobName = JobName;
356
+ exports.ManuallyFailedException = ManuallyFailedException;
357
+ exports.MaxAttemptsExceededException = MaxAttemptsExceededException;
358
+ exports.QueueServiceProvider = QueueServiceProvider;
359
+ exports.TimeoutExceededException = TimeoutExceededException;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,262 @@
1
1
  /// <reference path="./app.globals.d.ts" />
2
- import { ServiceProvider } from "@h3ravel/core";
2
+ import { ClassConstructor, JobPayload } from "@h3ravel/contracts";
3
+ import { Container, ServiceProvider } from "@h3ravel/core";
4
+ import { RuntimeException } from "@h3ravel/support";
3
5
 
6
+ //#region src/Contracts/JobContract.d.ts
7
+ type JobClassConstructor = (new (...args: any) => any);
8
+ //#endregion
9
+ //#region src/Jobs/Job.d.ts
10
+ declare abstract class Job {
11
+ /**
12
+ * The job handler instance.
13
+ */
14
+ protected instance: Job;
15
+ /**
16
+ * The IoC container instance.
17
+ */
18
+ protected container: Container;
19
+ /**
20
+ * Indicates if the job has been deleted.
21
+ */
22
+ protected deleted: boolean;
23
+ /**
24
+ * Indicates if the job has been released.
25
+ */
26
+ protected released: boolean;
27
+ /**
28
+ * Indicates if the job has failed.
29
+ */
30
+ protected failed: boolean;
31
+ /**
32
+ * The name of the connection the job belongs to.
33
+ */
34
+ protected connectionName: string;
35
+ /**
36
+ * The name of the queue the job belongs to.
37
+ */
38
+ protected queue?: string;
39
+ /**
40
+ * Get the job identifier.
41
+ */
42
+ abstract getJobId(): string | number | undefined;
43
+ /**
44
+ * Get the raw body of the job.
45
+ */
46
+ abstract getRawBody(): string;
47
+ /**
48
+ * Get the UUID of the job.
49
+ *
50
+ * @return string|null
51
+ */
52
+ uuid(): string | null;
53
+ /**
54
+ * Fire the job.
55
+ *
56
+ * @return void
57
+ */
58
+ fire(): void;
59
+ /**
60
+ * Delete the job from the queue.
61
+ */
62
+ delete(): void;
63
+ /**
64
+ * Determine if the job has been deleted.
65
+ */
66
+ isDeleted(): boolean;
67
+ /**
68
+ * Release the job back into the queue after (n) seconds.
69
+ *
70
+ * @param delay
71
+ */
72
+ release(delay?: number): void;
73
+ /**
74
+ * Determine if the job was released back into the queue.
75
+ *
76
+ * @return bool
77
+ */
78
+ isReleased(): boolean;
79
+ /**
80
+ * Determine if the job has been deleted or released.
81
+ */
82
+ isDeletedOrReleased(): boolean;
83
+ /**
84
+ * Determine if the job has been marked as a failure.
85
+ */
86
+ hasFailed(): boolean;
87
+ /**
88
+ * Mark the job as "failed".
89
+ */
90
+ markAsFailed(): void;
91
+ /**
92
+ * Delete the job, call the "failed" method, and raise the failed job event.
93
+ *
94
+ * @param e
95
+ */
96
+ fail(e: Error): void;
97
+ /**
98
+ * Determine if the current database transaction should be rolled back to level zero.
99
+ *
100
+ * @param e
101
+ */
102
+ protected shouldRollBackDatabaseTransaction(e: Error): any;
103
+ /**
104
+ * Process an exception that caused the job to fail.
105
+ *
106
+ * @param e
107
+ */
108
+ protected failedJob(e: Error, ..._args: any[]): void;
109
+ /**
110
+ * Resolve the given class.
111
+ */
112
+ protected resolve<C extends ClassConstructor>(className: C): InstanceType<C>;
113
+ /**
114
+ * Get the resolved job handler instance.
115
+ *
116
+ * @return mixed
117
+ */
118
+ getResolvedJob(): Job;
119
+ /**
120
+ * Get the decoded body of the job.
121
+ */
122
+ payload(): JobPayload;
123
+ /**
124
+ * Get the number of times to attempt a job.
125
+ *
126
+ * @return int|null
127
+ */
128
+ maxTries(): number | null;
129
+ /**
130
+ * Get the number of times to attempt a job after an exception.
131
+ *
132
+ * @return int|null
133
+ */
134
+ maxExceptions(): number | null;
135
+ /**
136
+ * Determine if the job should fail when it timeouts.
137
+ *
138
+ * @return bool
139
+ */
140
+ shouldFailOnTimeout(): boolean;
141
+ /**
142
+ * The number of seconds to wait before retrying a job that encountered an uncaught exception.
143
+ *
144
+ * @return int|int[]|null
145
+ */
146
+ backoff(): number | null;
147
+ /**
148
+ * Get the number of seconds the job can run.
149
+ *
150
+ * @return int|null
151
+ */
152
+ timeout(): number | null;
153
+ /**
154
+ * Get the timestamp indicating when the job should timeout.
155
+ *
156
+ * @return int|null
157
+ */
158
+ retryUntil(): number | null;
159
+ /**
160
+ * Get the name of the queued job class.
161
+ *
162
+ * @return string
163
+ */
164
+ getName(): string;
165
+ /**
166
+ * Get the resolved display name of the queued job class.
167
+ *
168
+ * Resolves the name of "wrapped" jobs such as class-based handlers.
169
+ */
170
+ resolveName(): any;
171
+ /**
172
+ * Get the class of the queued job.
173
+ *
174
+ * Resolves the class of "wrapped" jobs such as class-based handlers.
175
+ *
176
+ * @return string
177
+ */
178
+ resolveQueuedJobClass(): any;
179
+ /**
180
+ * Get the name of the connection the job belongs to.
181
+ */
182
+ getConnectionName(): string;
183
+ /**
184
+ * Get the name of the queue the job belongs to.
185
+ */
186
+ getQueue(): string | undefined;
187
+ /**
188
+ * Get the service container instance.
189
+ */
190
+ getContainer(): Container;
191
+ }
192
+ //#endregion
193
+ //#region src/Events/JobFailed.d.ts
194
+ declare class JobFailed {
195
+ connectionName: string;
196
+ job: Job;
197
+ exception: Error;
198
+ /**
199
+ * Create a new event instance.
200
+ *
201
+ * @param connectionName The connection name.
202
+ * @param job The job instance.
203
+ * @param exception The exception that caused the job to fail.
204
+ */
205
+ constructor(connectionName: string, job: Job, exception: Error);
206
+ }
207
+ //#endregion
208
+ //#region src/Exceptions/ManuallyFailedException.d.ts
209
+ declare class ManuallyFailedException extends RuntimeException {}
210
+ //#endregion
211
+ //#region src/Exceptions/MaxAttemptsExceededException.d.ts
212
+ declare class MaxAttemptsExceededException extends RuntimeException {
213
+ /**
214
+ * The job instance.
215
+ */
216
+ job: Job;
217
+ /**
218
+ * Create a new instance for the job.
219
+ *
220
+ * @param job
221
+ */
222
+ static forJob(job: Job): MaxAttemptsExceededException;
223
+ }
224
+ //#endregion
225
+ //#region src/Exceptions/TimeoutExceededException.d.ts
226
+ declare class TimeoutExceededException extends MaxAttemptsExceededException {
227
+ /**
228
+ * Create a new instance for the job.
229
+ *
230
+ * @param job
231
+ */
232
+ static forJob(job: Job): TimeoutExceededException;
233
+ }
234
+ //#endregion
235
+ //#region src/Jobs/JobName.d.ts
236
+ declare class JobName {
237
+ /**
238
+ * Parse the given job name into a class / method array.
239
+ *
240
+ * @param job
241
+ */
242
+ static parse(_job: string): [JobClassConstructor, string];
243
+ /**
244
+ * Get the resolved name of the queued job class.
245
+ *
246
+ * @param name
247
+ * @param payload
248
+ */
249
+ static resolve(name: string, payload: Record<string, any>): any;
250
+ /**
251
+ * Get the class name for queued job class.
252
+ *
253
+ * @param name
254
+ * @param payload
255
+ */
256
+ static resolveClassName(name: string, payload: Record<string, any>): any;
257
+ }
258
+ //#endregion
4
259
  //#region src/Providers/QueueServiceProvider.d.ts
5
-
6
260
  /**
7
261
  * Queues and workers.
8
262
  *
@@ -17,4 +271,4 @@ declare class QueueServiceProvider extends ServiceProvider {
17
271
  register(): void;
18
272
  }
19
273
  //#endregion
20
- export { QueueServiceProvider };
274
+ export { Job, JobClassConstructor, JobFailed, JobName, ManuallyFailedException, MaxAttemptsExceededException, QueueServiceProvider, TimeoutExceededException };
package/dist/index.js CHANGED
@@ -1,5 +1,339 @@
1
+ import { RuntimeException, tap } from "@h3ravel/support";
2
+ import { IDispatcher } from "@h3ravel/contracts";
1
3
  import { ServiceProvider } from "@h3ravel/core";
2
4
 
5
+ //#region src/Events/JobFailed.ts
6
+ var JobFailed = class {
7
+ /**
8
+ * Create a new event instance.
9
+ *
10
+ * @param connectionName The connection name.
11
+ * @param job The job instance.
12
+ * @param exception The exception that caused the job to fail.
13
+ */
14
+ constructor(connectionName, job, exception) {
15
+ this.connectionName = connectionName;
16
+ this.job = job;
17
+ this.exception = exception;
18
+ }
19
+ };
20
+
21
+ //#endregion
22
+ //#region src/Exceptions/ManuallyFailedException.ts
23
+ var ManuallyFailedException = class extends RuntimeException {};
24
+
25
+ //#endregion
26
+ //#region src/Exceptions/MaxAttemptsExceededException.ts
27
+ var MaxAttemptsExceededException = class MaxAttemptsExceededException extends RuntimeException {
28
+ /**
29
+ * The job instance.
30
+ */
31
+ job;
32
+ /**
33
+ * Create a new instance for the job.
34
+ *
35
+ * @param job
36
+ */
37
+ static forJob(job) {
38
+ return tap(new MaxAttemptsExceededException(job.resolveName() + " has been attempted too many times."), (e) => {
39
+ e.job = job;
40
+ });
41
+ }
42
+ };
43
+
44
+ //#endregion
45
+ //#region src/Exceptions/TimeoutExceededException.ts
46
+ var TimeoutExceededException = class TimeoutExceededException extends MaxAttemptsExceededException {
47
+ /**
48
+ * Create a new instance for the job.
49
+ *
50
+ * @param job
51
+ */
52
+ static forJob(job) {
53
+ return tap(new TimeoutExceededException(job.resolveName() + " has timed out."), (e) => {
54
+ e.job = job;
55
+ });
56
+ }
57
+ };
58
+
59
+ //#endregion
60
+ //#region src/Jobs/JobName.ts
61
+ var JobName = class {
62
+ /**
63
+ * Parse the given job name into a class / method array.
64
+ *
65
+ * @param job
66
+ */
67
+ static parse(_job) {
68
+ return [{}, ""];
69
+ }
70
+ /**
71
+ * Get the resolved name of the queued job class.
72
+ *
73
+ * @param name
74
+ * @param payload
75
+ */
76
+ static resolve(name, payload) {
77
+ if (!payload.displayName) return payload.displayName;
78
+ return name;
79
+ }
80
+ /**
81
+ * Get the class name for queued job class.
82
+ *
83
+ * @param name
84
+ * @param payload
85
+ */
86
+ static resolveClassName(name, payload) {
87
+ if (typeof payload.data.commandName === "string") return payload.data.commandName;
88
+ return name;
89
+ }
90
+ };
91
+
92
+ //#endregion
93
+ //#region src/Jobs/Job.ts
94
+ var Job = class {
95
+ /**
96
+ * The job handler instance.
97
+ */
98
+ instance;
99
+ /**
100
+ * The IoC container instance.
101
+ */
102
+ container;
103
+ /**
104
+ * Indicates if the job has been deleted.
105
+ */
106
+ deleted = false;
107
+ /**
108
+ * Indicates if the job has been released.
109
+ */
110
+ released = false;
111
+ /**
112
+ * Indicates if the job has failed.
113
+ */
114
+ failed = false;
115
+ /**
116
+ * The name of the connection the job belongs to.
117
+ */
118
+ connectionName;
119
+ /**
120
+ * The name of the queue the job belongs to.
121
+ */
122
+ queue;
123
+ /**
124
+ * Get the UUID of the job.
125
+ *
126
+ * @return string|null
127
+ */
128
+ uuid() {
129
+ return this.payload()["uuid"] ?? null;
130
+ }
131
+ /**
132
+ * Fire the job.
133
+ *
134
+ * @return void
135
+ */
136
+ fire() {
137
+ const payload = this.payload();
138
+ const [instance, method] = JobName.parse(payload["job"]);
139
+ (this.instance = this.resolve(instance))[method](this, payload["data"]);
140
+ }
141
+ /**
142
+ * Delete the job from the queue.
143
+ */
144
+ delete() {
145
+ this.deleted = true;
146
+ }
147
+ /**
148
+ * Determine if the job has been deleted.
149
+ */
150
+ isDeleted() {
151
+ return this.deleted;
152
+ }
153
+ /**
154
+ * Release the job back into the queue after (n) seconds.
155
+ *
156
+ * @param delay
157
+ */
158
+ release(delay = 0) {
159
+ this.released = true;
160
+ }
161
+ /**
162
+ * Determine if the job was released back into the queue.
163
+ *
164
+ * @return bool
165
+ */
166
+ isReleased() {
167
+ return this.released;
168
+ }
169
+ /**
170
+ * Determine if the job has been deleted or released.
171
+ */
172
+ isDeletedOrReleased() {
173
+ return this.isDeleted() || this.isReleased();
174
+ }
175
+ /**
176
+ * Determine if the job has been marked as a failure.
177
+ */
178
+ hasFailed() {
179
+ return this.failed;
180
+ }
181
+ /**
182
+ * Mark the job as "failed".
183
+ */
184
+ markAsFailed() {
185
+ this.failed = true;
186
+ }
187
+ /**
188
+ * Delete the job, call the "failed" method, and raise the failed job event.
189
+ *
190
+ * @param e
191
+ */
192
+ fail(e) {
193
+ this.markAsFailed();
194
+ if (this.isDeleted()) return;
195
+ if (this.shouldRollBackDatabaseTransaction(e)) this.container.make("db").connection(this.container.make("config").get("queue.failed.database")).rollBack(0);
196
+ try {
197
+ this.delete();
198
+ this.failedJob(e);
199
+ } finally {
200
+ this.resolve(IDispatcher).dispatch(new JobFailed(this.connectionName, this, e || new ManuallyFailedException()));
201
+ }
202
+ }
203
+ /**
204
+ * Determine if the current database transaction should be rolled back to level zero.
205
+ *
206
+ * @param e
207
+ */
208
+ shouldRollBackDatabaseTransaction(e) {
209
+ return e instanceof TimeoutExceededException && this.container.make("config").get("queue.failed.database") && ["database", "database-uuids"].includes(this.container.make("config").get("queue.failed.driver")) && this.container.has("db");
210
+ }
211
+ /**
212
+ * Process an exception that caused the job to fail.
213
+ *
214
+ * @param e
215
+ */
216
+ failedJob(e, ..._args) {
217
+ const payload = this.payload();
218
+ const [classInstance] = JobName.parse(payload.job);
219
+ this.instance = this.resolve(classInstance);
220
+ if (typeof this.instance.failed === "function") this.instance.failedJob(payload.data, e, payload.uuid ?? "", this);
221
+ }
222
+ /**
223
+ * Resolve the given class.
224
+ */
225
+ resolve(className) {
226
+ return this.container.make(className);
227
+ }
228
+ /**
229
+ * Get the resolved job handler instance.
230
+ *
231
+ * @return mixed
232
+ */
233
+ getResolvedJob() {
234
+ return this.instance;
235
+ }
236
+ /**
237
+ * Get the decoded body of the job.
238
+ */
239
+ payload() {
240
+ return JSON.parse(this.getRawBody());
241
+ }
242
+ /**
243
+ * Get the number of times to attempt a job.
244
+ *
245
+ * @return int|null
246
+ */
247
+ maxTries() {
248
+ return this.payload()["maxTries"] ?? null;
249
+ }
250
+ /**
251
+ * Get the number of times to attempt a job after an exception.
252
+ *
253
+ * @return int|null
254
+ */
255
+ maxExceptions() {
256
+ return this.payload()["maxExceptions"] ?? null;
257
+ }
258
+ /**
259
+ * Determine if the job should fail when it timeouts.
260
+ *
261
+ * @return bool
262
+ */
263
+ shouldFailOnTimeout() {
264
+ return this.payload()["failOnTimeout"] ?? false;
265
+ }
266
+ /**
267
+ * The number of seconds to wait before retrying a job that encountered an uncaught exception.
268
+ *
269
+ * @return int|int[]|null
270
+ */
271
+ backoff() {
272
+ return this.payload()["backoff"] ?? this.payload()["delay"] ?? null;
273
+ }
274
+ /**
275
+ * Get the number of seconds the job can run.
276
+ *
277
+ * @return int|null
278
+ */
279
+ timeout() {
280
+ return this.payload()["timeout"] ?? null;
281
+ }
282
+ /**
283
+ * Get the timestamp indicating when the job should timeout.
284
+ *
285
+ * @return int|null
286
+ */
287
+ retryUntil() {
288
+ return this.payload()["retryUntil"] ?? null;
289
+ }
290
+ /**
291
+ * Get the name of the queued job class.
292
+ *
293
+ * @return string
294
+ */
295
+ getName() {
296
+ return this.payload()["job"];
297
+ }
298
+ /**
299
+ * Get the resolved display name of the queued job class.
300
+ *
301
+ * Resolves the name of "wrapped" jobs such as class-based handlers.
302
+ */
303
+ resolveName() {
304
+ return JobName.resolve(this.getName(), this.payload());
305
+ }
306
+ /**
307
+ * Get the class of the queued job.
308
+ *
309
+ * Resolves the class of "wrapped" jobs such as class-based handlers.
310
+ *
311
+ * @return string
312
+ */
313
+ resolveQueuedJobClass() {
314
+ return JobName.resolveClassName(this.getName(), this.payload());
315
+ }
316
+ /**
317
+ * Get the name of the connection the job belongs to.
318
+ */
319
+ getConnectionName() {
320
+ return this.connectionName;
321
+ }
322
+ /**
323
+ * Get the name of the queue the job belongs to.
324
+ */
325
+ getQueue() {
326
+ return this.queue;
327
+ }
328
+ /**
329
+ * Get the service container instance.
330
+ */
331
+ getContainer() {
332
+ return this.container;
333
+ }
334
+ };
335
+
336
+ //#endregion
3
337
  //#region src/Providers/QueueServiceProvider.ts
4
338
  /**
5
339
  * Queues and workers.
@@ -16,4 +350,4 @@ var QueueServiceProvider = class extends ServiceProvider {
16
350
  };
17
351
 
18
352
  //#endregion
19
- export { QueueServiceProvider };
353
+ export { Job, JobFailed, JobName, ManuallyFailedException, MaxAttemptsExceededException, QueueServiceProvider, TimeoutExceededException };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h3ravel/queue",
3
- "version": "11.0.13",
3
+ "version": "11.1.0-alpha.2",
4
4
  "description": "Job queues, workers and broadcasting support system for H3ravel.",
5
5
  "h3ravel": {
6
6
  "providers": [
@@ -41,13 +41,13 @@
41
41
  "laravel"
42
42
  ],
43
43
  "peerDependencies": {
44
- "@h3ravel/core": "^1.21.6"
44
+ "@h3ravel/core": "^0.1.0-alpha.2",
45
+ "@h3ravel/contracts": "^0.1.0-alpha.2"
45
46
  },
46
47
  "devDependencies": {
47
48
  "typescript": "^5.4.0"
48
49
  },
49
50
  "scripts": {
50
- "barrel": "barrelsby --directory src --delete --singleQuotes",
51
51
  "build": "tsdown --config-loader unconfig",
52
52
  "dev": "tsx watch src/index.ts",
53
53
  "start": "node dist/index.js",