|
@@ -15,6 +15,9 @@ export class JobQueue {
|
|
|
this.currentJob = null;
|
|
this.currentJob = null;
|
|
|
this.jobIdCounter = 0;
|
|
this.jobIdCounter = 0;
|
|
|
|
|
|
|
|
|
|
+ // Track recently processed issue events to prevent duplicates
|
|
|
|
|
+ this.recentlyProcessed = new Map(); // key: "issues-15", value: timestamp
|
|
|
|
|
+
|
|
|
// Load existing queue from file
|
|
// Load existing queue from file
|
|
|
this.loadQueue();
|
|
this.loadQueue();
|
|
|
}
|
|
}
|
|
@@ -76,9 +79,33 @@ export class JobQueue {
|
|
|
* @param {object} payload - The webhook payload
|
|
* @param {object} payload - The webhook payload
|
|
|
* @param {object} headers - The webhook headers
|
|
* @param {object} headers - The webhook headers
|
|
|
* @param {object} config - The command configuration
|
|
* @param {object} config - The command configuration
|
|
|
- * @returns {object} The created job
|
|
|
|
|
|
|
+ * @returns {object|null} The created job or null if duplicate
|
|
|
*/
|
|
*/
|
|
|
enqueue(eventType, payload, headers, config) {
|
|
enqueue(eventType, payload, headers, config) {
|
|
|
|
|
+ // For issue events, check if we processed this recently (within 5 minutes)
|
|
|
|
|
+ if (eventType === 'issues' || eventType === 'issue_comment') {
|
|
|
|
|
+ const issueNumber = payload.issue?.number;
|
|
|
|
|
+ if (issueNumber) {
|
|
|
|
|
+ const key = `issue-${issueNumber}`;
|
|
|
|
|
+ const lastProcessed = this.recentlyProcessed.get(key);
|
|
|
|
|
+ const now = Date.now();
|
|
|
|
|
+
|
|
|
|
|
+ if (lastProcessed && (now - lastProcessed < 300000)) { // 5 minutes
|
|
|
|
|
+ logger.info(`Skipping duplicate job for ${key} (processed ${Math.round((now - lastProcessed)/1000)}s ago)`);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.recentlyProcessed.set(key, now);
|
|
|
|
|
+
|
|
|
|
|
+ // Cleanup old entries (older than 10 minutes)
|
|
|
|
|
+ for (const [k, ts] of this.recentlyProcessed.entries()) {
|
|
|
|
|
+ if (now - ts > 600000) {
|
|
|
|
|
+ this.recentlyProcessed.delete(k);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const job = {
|
|
const job = {
|
|
|
id: ++this.jobIdCounter,
|
|
id: ++this.jobIdCounter,
|
|
|
eventType,
|
|
eventType,
|