1

I am attempting to poll a MySQL DB by iterating every 2 seconds and retrieving all records created less than 2 seconds ago.

If I use setInterval it seems to occasionally miss a record. If I use setTimeout it only fetches the first iteration.

How can I fetch the data more reliably to include all data?

io.on('connection', function(socket) {
    authorize (socket, function(shop_id) {
        setInterval(function() {
            var sql = "SELECT * FROM `stats` WHERE `shop_id` = " + connection.escape(shop_id) +
            " AND `created` > DATE_SUB(NOW(), INTERVAL 2 SECOND)";
            var query = connection.query(sql, function(err, rows, fields) {
                if (err == null) {
                    console.log (rows);
                    socket.emit('newData', rows);
                }
            });
        }, 2000);
     });
});

1 Answer 1

3

MySQL is not designed to be pulled every 2 seconds. This is not a godo system architecture and you will experience more issues later on, definitely in regards to scalability.

setInterval is not precise and does not guarantee it will sleep for absolute 2000 ms, it may sleep for 2001, 2200, or even 50 hours.

To resolve this, store the most recent created that your NodeJS script fetched in a variable, and fetch all rows that are created AFTER your last received created. This will get every single record and won't miss records.

io.on('connection', function(socket) {


 authorize (socket, function(shop_id) {
        setInterval(function() {
            var lastCreated = toMySQLDate(new Date());
            var sql = "SELECT * FROM `stats` WHERE `shop_id` = " + connection.escape(shop_id) +
            " AND `created` > " + lastCreated + " ORDER BY `created` DESC";
            var query = connection.query(sql, function(err, rows, fields) {
                if (err == null) {
                    if (rows.length) {
                        lastCreated = toMySQLDate(rows[0].created);
                    }
                    console.log (rows);
                    socket.emit('newData', rows);
                }
            });
        }, 2000);
     });
});

function toMySQLDate(date) {
    return date.toISOString().slice(0, 19).replace('T', ' ');
}
Sign up to request clarification or add additional context in comments.

2 Comments

toMySQLDate() also needs to be used where lastCreated is updated. It won't let me edit the code example. Also typo in SQL = should be +
The stats data is not necessarily related to other tables in the database. What would be a better choice of data store for frequent polling with regards to scaling?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.