0

I'm new to realtime data viz and trying to build a dashboard app that displays CPU, memory, and battery data using the NodeJS systeminformation module. The React frontend uses Apollo Client to poll the server in 5 second intervals and the server calls a function that gets the necessary data and sends it back to the client to display on a graph.

I also want to write the data to a database (using InfluxDB for this). Would it be considered bad form to make my InfluxDB write request in the same function that retrieves the data and sends it to the client? I'm assuming this would slow down the process of getting the requested information back to the client and I'm wondering if there's a standard or cleaner way to do this.

This is the function that retrieves the data:

const getUpdatedData = async function () {
    const data = await Promise.all([
        si.system(),
        si.currentLoad(),
        si.mem(),
        si.battery(),
        si.processes()
    ]).then(results => {
        return {
            id: uuidv1(),
            deviceID: results[0].uuid,
            timestamp: Date.now(),
            cpuTotal: results[1].currentLoad,
            cpuSys: results[1].currentLoadSystem,
            cpuUser: results[1].currentLoadUser,
            memUsed: results[2].used,
            memFree: results[2].free,
            battPercent: results[3].percent,
            battRemaining: results[3].timeRemaining,
            battCharging: results[3].isCharging,
            battCycles: results[3].cycleCount,
            processes: results[4].list.slice(0, 5).map(process => ({ name: process.name, cpu: process.cpu, mem: process.mem, started: process.started }))
        }
    })

    // Possible location of function to write data to DB?

    return data;
}

And here is the resolver that sets data to be passed to the client:

const resolvers = {
    Query: {
        systemData: () => getUpdatedData().then(data => data)
    },
};

The client side code that polls the data:

const { loading, error, data } = useQuery(GET_DATA, {
    pollInterval: 5000,
    onCompleted: data => updatePoints([...points, data.systemData])
})

I have also considered using an Apollo subscription and a setInterval on the server side, which would use a WebSocket to push the data from the server to the client. I could then write the same data to the database in a separate function. I think that this approach might make it harder to graph at precise intervals, since I don't have control over the intervals on the client side. Polling seems to guarantee that I receive the data exactly when I want it but I could be wrong on this.

Any help would be extremely appreciated!

0 Answers0