feat: add in-process mutex to prevent concurrent scraper runs
All checks were successful
CI/CD Pipeline - Apartment API / Scan Dependencies (pull_request) Successful in 13s
CI/CD Pipeline - Apartment API / Lint & Test (pull_request) Successful in 38s
CI/CD Pipeline - Apartment API / Send Webhook Notification (pull_request) Successful in 2s
CI/CD Pipeline - Apartment API / Build & Push Image (pull_request) Has been skipped
CI/CD Pipeline - Apartment API / Deploy to Production (pull_request) Has been skipped
All checks were successful
CI/CD Pipeline - Apartment API / Scan Dependencies (pull_request) Successful in 13s
CI/CD Pipeline - Apartment API / Lint & Test (pull_request) Successful in 38s
CI/CD Pipeline - Apartment API / Send Webhook Notification (pull_request) Successful in 2s
CI/CD Pipeline - Apartment API / Build & Push Image (pull_request) Has been skipped
CI/CD Pipeline - Apartment API / Deploy to Production (pull_request) Has been skipped
Implement a lightweight in-process mutex lock for the scraper job scheduler. This prevents multiple scraper instances from running simultaneously, which could cause duplicate data and race conditions. Exported functions: - acquireLock(jobId): Attempts to acquire the mutex, returns boolean - releaseLock(): Releases the mutex lock - isScraperRunning(): Returns current lock state - getCurrentJobId(): Returns the active job ID or null Includes 19 unit tests covering lock acquisition, release, re-entry prevention, and edge cases.
This commit is contained in:
48
jobs/scraperJob.js
Normal file
48
jobs/scraperJob.js
Normal file
@ -0,0 +1,48 @@
|
||||
// In-process mutex state
|
||||
let isRunning = false;
|
||||
let currentJobId = null;
|
||||
|
||||
/**
|
||||
* Check if scraper is currently running
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isScraperRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current job ID if running
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function getCurrentJobId() {
|
||||
return currentJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the scraper lock
|
||||
* @param {string} jobId - Job ID to set
|
||||
* @returns {boolean} True if lock acquired
|
||||
*/
|
||||
function acquireLock(jobId) {
|
||||
if (isRunning) {
|
||||
return false;
|
||||
}
|
||||
isRunning = true;
|
||||
currentJobId = jobId;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the scraper lock
|
||||
*/
|
||||
function releaseLock() {
|
||||
isRunning = false;
|
||||
currentJobId = null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isScraperRunning,
|
||||
getCurrentJobId,
|
||||
acquireLock,
|
||||
releaseLock
|
||||
};
|
||||
Reference in New Issue
Block a user