Почему Express res. json () задерживает Google Sheets API на +30 секунд - PullRequest
2 голосов
/ 16 марта 2020

Я создаю приложение, которое ищет определение слова в листе Google из команды Slack sla sh . Приложение размещено в облачных функциях Google и написано в Node.js.

Чтобы установить ограничение времени 3000 мс для слабых команд, приложение

  1. отправляет немедленный 200 OK ответ, затем
  2. выполняет поиск в Sheets, и, наконец,
  3. возвращает полный ответ через request_url Slack, как определено в документации Slack .

Пока все хорошо. Но вот кикер:

Когда я вызываю res.json() в моей основной функции glossary, Slack get - это первоначальный ответ, , но sendMessageToSlackResponseURL() не вызывается для других 10- 40 секунд В итоге я получаю ответ в Slack, как и ожидалось, хотя и мучительно медленный.

Я сузил его (смущающим количеством console.log() звонков) до строки:

const reply = (await sheets.spreadsheets.values.get(request)).data.values;

Эта команда запускается в течение 2-3 секунд, если res.json() - это , а не , вызванный ранее - едва установленный временной интервал Slack. Но если res.json() называется , то он вызывается ранее. Эта команда занимает до 40 секунд.

Как на вызов API Google Sheets повлиял предыдущий вызов res.json()? Чего мне не хватает?

// Simplified code pasted below:

exports.glossary = async (req, res) => {

    // Give immediate response to prevent 3000ms Slack timeout.
    res.json(initSlackResponse(req.body.text)); //Commenting out this line speeds up the app

    // Get glossary result from Google Sheet
    let response = await getGlossaryResults(query);

    // Return late response
    await sendMessageToSlackResponseURL(req.body.response_url, response);

    return Promise.resolve();
};

const getGlossaryResults = async (query) => {

    const content = await readFile(CREDENTIALS_PATH);
    let oAuth2Client = await authorize(JSON.parse(content));
    const request = {
        spreadsheetId: spreadsheetId,
        range: range,
        auth: oAuth2Client
    };
    //The following command takes 10-40 seconds to run if res.json(initSlackResponse(query)); has been called. 
    //If res.json() is *not* called, the command takes 2-3 seconds.
    const reply = (await sheets.spreadsheets.values.get(request)).data.values;

    // *Generate the results here
    return results;
};

function sendMessageToSlackResponseURL(responseURL, JSONmessage) {

    let postOptions = {
        uri: responseURL,
        method: 'POST',
        headers: {
            'Content-type': 'application/json'
        },
        json: JSONmessage
    };

    request(postOptions, (error) => {
        if (error){
            console.error(error);
        }
    });
    return Promise.resolve();
}

const initSlackResponse = (query) => {
    return {
        // *Build simple json object here
    };
};
...