NodeJS Kafka初始化导致计时问题

时间:2019-07-09 02:58:16

标签: javascript node.js apache-kafka node-kafka

我有一段简单的代码,可以使用fs读取JSON文件。我正在使用回调,并在获得数据后将其用于配置应用程序的另一部分。

如果我不使用超时,或者将事件处理程序放入fs回调中,则会引发错误。

/**
 * 
 * consumer.js 
 * 
 * Subscribes to a kafka topic to consume
 * messages sent by our producer.
 * 
 */

// Defined constants
const kafka = require('kafka-node'),
    Consumer = kafka.Consumer,
    client = new kafka.KafkaClient(),
    utilities = require('./utilities'),
    fs = require('fs');

// Defined vars
let consumer = {};

// Load our topics to subscribe to
fs.readFile('./json/topics.json', readTopicFile);

/**
 * Handle our file load
 * @param {*} err 
 * @param {*} data 
 */
function readTopicFile(err, data) {

    // Handle file read error
    if (err) {
        utilities.logError('Error reading topic file', err);
        return;
    }

    // Define our topic data
    let obj = JSON.parse(data);

    // Define our consumer
    consumer = new Consumer(
        client,
        obj,
        {
            autoCommit: false,
            fromOffset: 'latest'
        }
    );

    // Start out consumer
    setTimeout(function () {
        startConsumer();
    }, 100);

}


/**
 * Wait for messages from our subscribed topics
 */
function startConsumer() {
    console.log('consumer waiting for data ...')
    consumer.on('message', function (message) {
        utilities.storeRecord(message); // Error in this utility function if timeout isn't in place
    });
}

对于上下文,这是我的实用程序文件:

storeRecord: function (payload) {

        // Define our postgres instance
        var pg = require('pg');
        var utilities = require('./utilities');

        // Connect to the postgres instance
        pg.connect(process.env.DATABASE_URL, function (err, conn, done) {

            // watch for any connect issues
            if (err) {
                logError('Unable to connect to postgres', err);
            }

            // Check to see if we got our payload
            if (payload) {

                // Holds our payload data
                const val = JSON.parse(payload.value).data; // <<<--- Without the setTimeout on the consumer.js, this throws the error.

                // Insert the data
                const sql = 'INSERT INTO communications (firstname, lastname, age, department, campus, state) VALUES ($1, $2, $3, $4, $5, $6)';
                const values = [val.firstName, val.lastName, val.age, val.department, val.campus, val.state];

                conn.query(sql, values, (err, result) => {
                    done();
                    if (err) {
                        utilities.logError('Error inserting data into table', err);
                    } else {
                        utilities.logError('Inserted data', result);
                    }
                });

            }
        });
    }

在上面的代码中,我的utilities.storeRecord在期望从message获取数据的地方抛出错误。

我的问题是关于为什么使用setTimeout可以解决计时问题。我的实用程序文件引发的错误是TypeError: Cannot read property 'data' of null

据我所知,好像new Consumer没时间初始化并且不知道它正在使用fromOffset: 'latest'。我认为情况确实如此,因为message事件中不应包含consumer.on('message', ...

如果我登录message超时,则没有数据通过。如果我在没有超时的情况下登录message,它将列出主题开头的所有消息(因为它不知道我们只需要最新消息)。

我坚持使用此超时还是有一种更好的方法来初始化Consumer,以便事件能更快地知道它?

0 个答案:

没有答案