breejs / bree

Bree is a Node.js and JavaScript job task scheduler with worker threads, cron, Date, and human syntax. Built for @ladjs, @forwardemail, @spamscanner, @cabinjs.

Home Page:https://jobscheduler.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[question] Concurrency when using 1 second interval

Echelpoel opened this issue · comments

In my app I need to run a job each second to see if the finished_at value of some records has passed, and if so, delete it. In order to do so I set up a job with interval: '1s' where a connection with MongoDB is made (through Mongoose) and the action is performed.

The problem is, because the job takes longer than 1 second to complete, I'm getting lots of Error: Job is already running errors because the next job is already starting. I believe the solution for this is implementing concurrency (through p-queue as stated in the docs) but I can't get it to work.

Any ideas to point me in the right direction?
Thanks!

I would probably create one long running task and then use p-queue to actually manage the removal of the docs.

Another option would be to setup multiple jobs firing at different intervals. Although this could lead to a race condition.

Thanks, got it working with a long running task:

index.ts

const bree = new Bree({
  root: path.join(__dirname, 'src/jobs'),
  defaultExtension: process.env.NODE_ENV === 'development' ? 'ts' : 'js',
  jobs: [
    { name: 'check-finished' }
  ]
})
const graceful = new Graceful({ brees: [bree] })

graceful.listen()
bree.start()

src/jobs/check-finished.ts

import { parentPort } from 'worker_threads'
import PQueue from 'p-queue'
import process from 'process'
import mongoose from 'mongoose'
import 'dotenv/config'

const queue = new PQueue({ concurrency: 5 })

const checkFinishedJob = () =>
  // logic goes here
  true

;(() => {
  if (parentPort) {
    await mongoose.connect(process.env.MONGODB_URL as string)

    setInterval(() => {
      queue.add(() => checkFinishedJob())
    }, 1000) // run each second
  } else {
    process.exit(0)
  }
})()