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

Aws lambda 建议处理多个lambda调用的方法,aws-lambda,slack,Aws Lambda,Slack,主要问题: Lambda函数在成功的外部API调用后未退出,从而触发多个外部API调用 我有一个lambda函数,它在事件发生时侦听空闲事件,调用lambda函数。我使用一些条件检查过滤这些事件,当目标事件发生时,我进行外部API调用 但是,上述所有方法都有效,每个事件都会多次触发外部API调用(如果成功,则触发次数应为1,但触发次数约为4次) 幂等元 -通常人们会把这个问题与幂等性联系起来,但是,考虑到条件块中的外部API调用会被触发更多次,我认为这不是一个问题 我可以确认条件检查是否正确过

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

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

但是,上述所有方法都有效,每个事件都会多次触发外部API调用(如果成功,则触发次数应为1,但触发次数约为4次)

幂等元 -通常人们会把这个问题与幂等性联系起来,但是,考虑到条件块中的外部API调用会被触发更多次,我认为这不是一个问题

  • 我可以确认条件检查是否正确过滤了适当的事件
  • 在后续(附加)外部API调用之前,我可以确认我正在接收一个
    statusCode 200
  • 我已经包括了
    context.done()
    和冗余的
    callback()
    ,但运气不好
寻找一些建议方法

  • 有没有人提出了解决这个问题的建议
  • 我读过一些人使用DynamoDB跟踪执行请求,但这听起来不是一个好方法
我在下面附加了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);
    }
};
预期行为

  • 在调用和条件检查时进行单个外部API调用;响应后退出。状态===200
问题(你不是第一个也不会是最后一个问这类问题的人,AWS需要尽快修复文档)是因为你把
async/wait
context.done
callback()
调用混淆了

如果您的函数已经是
异步的
,那么请始终坚持
等待
,忘记
上下文
回调
对象

请注意,
sendMessages
async
,因此它会返回一个承诺,但您不会使用该承诺执行任何操作。你应该等待它。我已经相应地更改了您的代码,并且去掉了
上下文
回调
对象,您不需要它们

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网关调用,则需要返回一个2xx状态代码(或在出现错误时返回4xx和5xx)和一个字符串化的主体,以便它可以正确终止,如下所示:

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

@约翰罗滕斯坦,请你联系文档团队,看看他们能否更新文档?我曾经联系过@SebastienStomarq,他说他已经和docs团队谈过了,但到目前为止还没有更新文档。现在,我们要回答的大多数问题都是关于
async/await
context
callback
调用结合使用,造成了绝对的混乱。如果文档未修复,这些问题将不断出现。@ThalesMinussi您可以单击文档页面上的“反馈”按钮,该按钮将发送给文档团队。但是,如果您想写一个更详细的解释,请随时发电子邮件给我,我会向文档团队提出。(我不是节点人,所以最好让熟悉大多数问题的人为他们记录问题。)@JohnRotenstein Perfect。当我有时间写详细的解释时,我会这样做。谢谢你抽出时间给我回电话。也许开源文档会是一个好主意…@ThalesMinussi AWS文档可以在github上获得,因此您可以提交请求(但我不确定所有手册都在那里)。@JohnRotenstein我已经着手创建了PR。让我们看看你们AWS和社区的反应。谢谢你们的回复。这很有道理,我已经相应地重构了lambda函数,但是问题仍然存在。既然我正在等待sendMessages承诺,那么我是否应该对响应执行任何操作以终止/退出lambda处理程序中的函数?非常欢迎。不是真的…那个
返回{message:'Success}
块应该能够处理它。除非这是来自API网关的调用。是这样吗?如果是这样,您需要添加状态码并将主体字符串化。我会更新我的答案。