1 |
rakin |
421 |
import DiscordClient from "../../client/Client"; |
2 |
rakin |
430 |
import { generate as randomstring } from 'randomstring'; |
3 |
rakin |
429 |
import { IQueuedJob } from "../../models/QueuedJob"; |
4 |
rakin |
421 |
|
5 |
|
|
export interface QueueOptions { |
6 |
|
|
runAfter?: number; |
7 |
|
|
id?: string; |
8 |
|
|
runAt?: Date; |
9 |
|
|
model: IQueuedJob; |
10 |
|
|
} |
11 |
|
|
|
12 |
|
|
export default abstract class Queue { |
13 |
|
|
protected completed = false; |
14 |
rakin |
430 |
public readonly runOn: number = 0; |
15 |
rakin |
421 |
public readonly id: string; |
16 |
rakin |
430 |
public readonly model: IQueuedJob; |
17 |
rakin |
421 |
protected readonly timeout: NodeJS.Timeout; |
18 |
rakin |
430 |
public readonly guild: string | undefined; |
19 |
rakin |
421 |
|
20 |
|
|
constructor(protected client: DiscordClient, { runAfter, id, runAt, model }: QueueOptions) { |
21 |
|
|
if (runAfter !== 0 && runAfter !== 0 && !runAfter && !runAt) { |
22 |
|
|
throw new Error("One of runAfter or runAt must be specified for creating a queue"); |
23 |
|
|
} |
24 |
|
|
|
25 |
|
|
this.runOn = runAfter ? Date.now() + runAfter : runAt!.getTime(); |
26 |
rakin |
430 |
this.id = id ?? randomstring(7); |
27 |
rakin |
421 |
this.model = model; |
28 |
rakin |
430 |
this.guild = model.guild; |
29 |
rakin |
421 |
|
30 |
|
|
const ms = this.runOn - Date.now(); |
31 |
|
|
|
32 |
|
|
this.timeout = setTimeout(async () => { |
33 |
|
|
await this.run(); |
34 |
|
|
await this.finish(); |
35 |
|
|
}, ms < 0 ? 0 : ms); |
36 |
|
|
|
37 |
|
|
console.log('Queue created: ', this.constructor.name, this.id); |
38 |
|
|
} |
39 |
|
|
|
40 |
rakin |
428 |
get data() { |
41 |
|
|
return this.model.data; |
42 |
|
|
} |
43 |
|
|
|
44 |
rakin |
421 |
async finish() { |
45 |
|
|
this.client.queueManager.removeQueue(this); |
46 |
|
|
console.log("Job complete: ", this.constructor.name); |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
async cancel() { |
50 |
|
|
clearTimeout(this.timeout); |
51 |
|
|
await this.model.delete(); |
52 |
rakin |
428 |
this.client.queueManager.removeQueue(this); |
53 |
rakin |
421 |
} |
54 |
|
|
|
55 |
|
|
abstract execute(data?: { [key: string | number]: any }): Promise<any>; |
56 |
|
|
|
57 |
|
|
async run() { |
58 |
|
|
this.completed = true; |
59 |
|
|
this.model.delete(); |
60 |
rakin |
424 |
|
61 |
|
|
try { |
62 |
|
|
return await this.execute(this.model.data); |
63 |
|
|
} |
64 |
|
|
catch (e) { |
65 |
|
|
console.error(`An error occurred in queue job\nJob ID: ${this.id}`, e); |
66 |
|
|
} |
67 |
rakin |
421 |
} |
68 |
|
|
} |