dt-common-device 7.6.11 → 7.6.12
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.
|
@@ -12,5 +12,32 @@ export declare class WebhookQueueService implements IWebhookQueue {
|
|
|
12
12
|
* Creates queue if it doesn't exist
|
|
13
13
|
*/
|
|
14
14
|
addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Mark a webhook job as completed (processed successfully)
|
|
17
|
+
*/
|
|
18
|
+
markWebhookCompleted(propertyId: string, pmsType: string, jobId: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Mark a webhook job as failed
|
|
21
|
+
*/
|
|
22
|
+
markWebhookFailed(propertyId: string, pmsType: string, jobId: string, error?: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
25
|
+
* This method will discover all queues in Redis and filter only webhook queues
|
|
26
|
+
*/
|
|
27
|
+
pollWebhookFromQueues(): Promise<{
|
|
28
|
+
jobId: string;
|
|
29
|
+
data: any;
|
|
30
|
+
propertyId: string;
|
|
31
|
+
pmsType: string;
|
|
32
|
+
queueName: string;
|
|
33
|
+
} | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Get all available webhook queue names from Redis
|
|
36
|
+
*/
|
|
37
|
+
getAllQueueNames(): Promise<string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Get total waiting count across all webhook queues
|
|
40
|
+
*/
|
|
41
|
+
getTotalWaitingCount(): Promise<number>;
|
|
15
42
|
static getOrCreateQueue(queueKey: string, queues: Map<string, any>): any;
|
|
16
43
|
}
|
|
@@ -78,6 +78,153 @@ let WebhookQueueService = (() => {
|
|
|
78
78
|
});
|
|
79
79
|
return job.id;
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Mark a webhook job as completed (processed successfully)
|
|
83
|
+
*/
|
|
84
|
+
async markWebhookCompleted(propertyId, pmsType, jobId) {
|
|
85
|
+
const queueName = this.generateQueueName(propertyId, pmsType);
|
|
86
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
87
|
+
throw new Error(`Queue ${queueName} does not exist`);
|
|
88
|
+
}
|
|
89
|
+
const queue = this.webhookQueues.get(queueName);
|
|
90
|
+
const job = await queue.getJob(jobId);
|
|
91
|
+
if (job) {
|
|
92
|
+
// Mark job as completed - it will be removed after TTL
|
|
93
|
+
await job.moveToCompleted();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Mark a webhook job as failed
|
|
98
|
+
*/
|
|
99
|
+
async markWebhookFailed(propertyId, pmsType, jobId, error) {
|
|
100
|
+
const queueName = this.generateQueueName(propertyId, pmsType);
|
|
101
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
102
|
+
throw new Error(`Queue ${queueName} does not exist`);
|
|
103
|
+
}
|
|
104
|
+
const queue = this.webhookQueues.get(queueName);
|
|
105
|
+
const job = await queue.getJob(jobId);
|
|
106
|
+
if (job) {
|
|
107
|
+
// Mark job as failed - it will be removed after TTL
|
|
108
|
+
await job.moveToFailed(new Error(error || "Job processing failed"));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
113
|
+
* This method will discover all queues in Redis and filter only webhook queues
|
|
114
|
+
*/
|
|
115
|
+
async pollWebhookFromQueues() {
|
|
116
|
+
try {
|
|
117
|
+
// Get all queue names from Redis (not just local Map)
|
|
118
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
119
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
120
|
+
// Filter only webhook queues (PropertyId_pmsType_webhook pattern)
|
|
121
|
+
const webhookQueueKeys = queueKeys
|
|
122
|
+
.map((key) => key.replace("bull:", "").replace(":id", ""))
|
|
123
|
+
.filter((queueName) => {
|
|
124
|
+
const parts = queueName.split("_");
|
|
125
|
+
return parts.length === 3 && parts[2] === "webhook";
|
|
126
|
+
});
|
|
127
|
+
// Check each webhook queue for waiting jobs
|
|
128
|
+
for (const queueName of webhookQueueKeys) {
|
|
129
|
+
try {
|
|
130
|
+
// Create queue instance if not exists locally
|
|
131
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
132
|
+
const { Queue } = require("bullmq");
|
|
133
|
+
const queue = new Queue(queueName, {
|
|
134
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
135
|
+
});
|
|
136
|
+
this.webhookQueues.set(queueName, queue);
|
|
137
|
+
}
|
|
138
|
+
const queue = this.webhookQueues.get(queueName);
|
|
139
|
+
const waitingJobs = await queue.getWaiting(0, 1);
|
|
140
|
+
if (waitingJobs.length > 0) {
|
|
141
|
+
const job = waitingJobs[0];
|
|
142
|
+
// Mark job as active (this prevents other consumers from picking it up)
|
|
143
|
+
await job.moveToActive();
|
|
144
|
+
// Extract propertyId and pmsType from queue name
|
|
145
|
+
const parts = queueName.split("_");
|
|
146
|
+
const propertyId = parts[0];
|
|
147
|
+
const pmsType = parts[1];
|
|
148
|
+
return {
|
|
149
|
+
jobId: job.id,
|
|
150
|
+
data: job.data,
|
|
151
|
+
propertyId,
|
|
152
|
+
pmsType,
|
|
153
|
+
queueName,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(`Error checking queue ${queueName}:`, error);
|
|
159
|
+
continue; // Try next queue
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return null; // No jobs available in any webhook queue
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.error("Error discovering queues from Redis:", error);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get all available webhook queue names from Redis
|
|
171
|
+
*/
|
|
172
|
+
async getAllQueueNames() {
|
|
173
|
+
try {
|
|
174
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
175
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
176
|
+
// Filter only webhook queues (PropertyId_pmsType_webhook pattern)
|
|
177
|
+
return queueKeys
|
|
178
|
+
.map((key) => key.replace("bull:", "").replace(":id", ""))
|
|
179
|
+
.filter((queueName) => {
|
|
180
|
+
const parts = queueName.split("_");
|
|
181
|
+
return parts.length === 3 && parts[2] === "webhook";
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error("Error getting queue names from Redis:", error);
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get total waiting count across all webhook queues
|
|
191
|
+
*/
|
|
192
|
+
async getTotalWaitingCount() {
|
|
193
|
+
try {
|
|
194
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
195
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
196
|
+
let totalCount = 0;
|
|
197
|
+
// Filter only webhook queues and count waiting jobs
|
|
198
|
+
for (const key of queueKeys) {
|
|
199
|
+
const queueName = key.replace("bull:", "").replace(":id", "");
|
|
200
|
+
const parts = queueName.split("_");
|
|
201
|
+
// Only count webhook queues
|
|
202
|
+
if (parts.length === 3 && parts[2] === "webhook") {
|
|
203
|
+
try {
|
|
204
|
+
// Create queue instance if not exists locally
|
|
205
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
206
|
+
const { Queue } = require("bullmq");
|
|
207
|
+
const queue = new Queue(queueName, {
|
|
208
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
209
|
+
});
|
|
210
|
+
this.webhookQueues.set(queueName, queue);
|
|
211
|
+
}
|
|
212
|
+
const queue = this.webhookQueues.get(queueName);
|
|
213
|
+
const waitingJobs = await queue.getWaiting();
|
|
214
|
+
totalCount += waitingJobs.length;
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
console.error(`Error getting count for queue ${queueName}:`, error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return totalCount;
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error("Error getting total waiting count:", error);
|
|
225
|
+
return 0;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
81
228
|
static getOrCreateQueue(queueKey, queues) {
|
|
82
229
|
return (queues.get(queueKey) ??
|
|
83
230
|
queues
|