Child process setInterval sporadically not firing

时间秒杀一切 提交于 2021-01-29 08:08:21

问题


My application places bets on certain sporting events. Almost like an automatic betting bot. A part of this is to track the current status of the event so it can make an informed calculation whether to place a bet or not. To do this, I poll the status of an event every minute using setInterval. A single sporting event is "watched" by 1 child process. There could be up 100+ sporting events at any one time meaning there could be 100+ child process' spawned & actively polling.

worker/index.js

const logger = require('../lib/logger/winston')
const utils = {
    updateEventState: require('../utils/update-event-state')
}
const db = require('../db')

let eventStatesInterval

module.exports = async function() {
    try {
        logger.info(`[STARTED FOR EVENT ${process.EVENT_ID} (Process: ${process.pid})]`)

        const event = await db.getEvent(process.EVENT_ID)

        logger.info(`[STARTING STATE POLLING FOR EVENT (${process.EVENT_ID} - Process: ${process.pid})]`)

        eventStatesInterval = setInterval(utils.updateEventState, 60000, event) // 1 min

        process.on('exit', code => {
            clearInterval(eventStatesInterval)
        })
    } catch(err) {
        throw err
    }
}

utils/update-event-state.js

const logger = require('../lib/logger/winston')
const db = require('../db')

module.exports = async function(event) {
    try {
        const update = {}

        if (!process.CHECKING_EVENT) {
            process.CHECKING_EVENT = true

            logger.info(`[POLLING STATE (${process.EVENT_ID} - Process: ${process.pid})]`)

            // Some async operations polling APIs to get the full status of an event
            const hasEnded = await api.getHasEventEnded(process.EVENT_ID)

            await db.updateEvent(process.EVENT_ID, update)

            if (hasEnded) {
                process.exit(0)
            }
            process.CHECKING_EVENT = false
        }
    } catch(err) {
        throw err
    }
}

It's also worth noting that a single child process could have more setInterval process' further down the line. For example, if I place a bet that is not fully matched. I poll to check when/if it gets matched. This is also run on a setInterval basis (about every 5 secs). Check ing the logs, some process' are polled correctly every minute but a couple (inconsistent number each time) are not being polled at all. Looking at the logs for a specific process, I get:

For reference, the current time was 22:33 when that screenshot was taken so the interval had not happened in over an hour

There was only 4 events (child process') running at the time.

That is an example screenshot. A process can log several interval callbacks & then just...stop. No more logs at all. No errors or anything. Just stops.

This application runs on a Digital Ocean box with 4GB memory & 2 vCPUs. The app is dockerised. When running docker stats, 100% CPU is being used constantly. When starting with docker run, I limit the memory usage but not the CPU. Could this be the issue? Would setInterval callback liable not be invoked due to CPU constraints?

It's worth noting that this feature to poll the event state is new (5 days) & I had never had an issue with setInterval beforehand (I don't know how much CPU was being used though). I was initially polling the state every 30 seconds & when I noticed this problem. When I checked docker stats, almost 200% CPU usage was shown. Lowering it to 1 minute instead has fixed that slightly. I have the process.CHECKING_EVENT global bool there to not block the thread & not cause a pile up of tasks on the stack.

来源:https://stackoverflow.com/questions/65030139/child-process-setinterval-sporadically-not-firing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!