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

时间:2019-07-18 09:26:11

标签: aws-lambda slack

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

我有一个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调用;在response.status === 200后退出

1 个答案:

答案 0 :(得分:1)

问题(您不是第一个也不是最后一个会问这种类型的问题,AWS需要尽快修复文档)是因为您将async/awaitcontext.done混合在一起,并且callback()个呼叫。

如果您的功能已经是async,那么请一直坚持使用await,而忽略contextcallback对象。

看到sendMessagesasync,因此它返回一个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网关调用,则您需要返回带有字符串主体的2xx状态代码(如果发生错误,则返回4xx和5xx),以便其可以正确终止,例如:

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