建议处理多个 lambda 调用的方法

Suggest approach for handling multiple lambda invocations

主要问题: Lambda 函数在外部 API 调用成功后未退出,随后触发多个外部 API 调用。

我有一个 lambda 函数,它在调用 lambda 函数时监听松弛事件。我使用一些条件检查来过滤这些事件,当目标事件发生时,我进行外部 API 调用。

以上所有工作,但是,外部 API 调用在每个事件中被触发多次(如果成功,它应该是 1 次约 4 次)。

幂等 - 通常人们将此问题与幂等性联系起来,但是,考虑到它在条件块中的外部 API 调用被触发了额外的次数,我不认为这是一个问题。

寻找一些建议的方法

我在下面附加了 lambda 函数:

const axios = require('axios');

const sendMessages = async(event, context, callback) => {
    // test the message for a match
    if (event.type === 'message' && event.bot_id !== undefined) {
        console.log("filter events for specific event");

        let URL = 'https://someurl.com/slack/events';
        let response = await axios.post(URL, {
            events: event,
        });
        console.log("response success :: ", response.status);
        if (response.status === 200) {
            console.log("condition met");
            context.done();
            callback(null, 'successful request');
        }
    }
    callback(null, 'successful request');
};

// Lambda handler
exports.server = (data, context, callback) => {
    let eventData = JSON.parse(data.body);
    switch (data.path) {
        case "/slack-events": sendMessages(eventData.event, context, callback); break;
        default: callback(null);
    }
};

预期行为

问题(您不是第一个也不会是最后一个问此类问题的人,AWS 需要尽快修复文档)是因为您混淆了 async/awaitcontext.donecallback() 个电话。

如果你的函数已经是 async,那么一直坚持使用 await,忘记 contextcallback 对象。

看到 sendMessagesasync,因此它 return 是一个 Promise,但您不对该 Promise 做任何事情。你应该 await 就可以了。我已经相应地更改了您的代码并删除了 contextcallback 对象,您不需要它们。

const axios = require('axios');

const sendMessages = async (event) => {
  // test the message for a match
  if (event.type === 'message' && event.bot_id !== undefined) {
    console.log('filter events for specific event');

    let URL = 'https://someurl.com/slack/events';
    let response = await axios.post(URL, {
      events: event,
    });
    console.log('response success :: ', response.status);
    return response;
  }
  return Promise.resolve({});
};

// Lambda handler
exports.server = async (event) => {
  let eventData = JSON.parse(event.body);
  switch (event.path) {
    case '/slack-events':
      await sendMessages(eventData.event);
      break;
  }
  return {
    message: 'Success',
  }
};

如果此 Lambda 由 API 网关调用,则您需要 return 带有字符串化主体的 2xx 状态代码(或 4xx 和 5xx,以防出错),以便它可以正确终止,像这样:

return {
        statusCode: 200,
        body: JSON.stringify({message: 'Success'})
      }