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.