java - AWS Lambda 热函数重新发送代码,如何停止?

标签 java amazon-web-services aws-lambda

所以我的代码执行了多次,几乎就像它返回到代码中并以某种方式重新执行......

此代码在Intent上执行

@Override
public void onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope, Intent intent, String name) {
    IntentRequest request = requestEnvelope.getRequest();
    switch (request.getDialogState()) {
        case STARTED:
            this.speechletResponse = Response.getDialogueResponse(intent, true);
            break;
        case IN_PROGRESS:
            this.speechletResponse = Response.getDialogueResponse(intent, false);
            break;
        case COMPLETED:
            String numberString = intent.getSlot(SlotTitle.ID).getValue();
            if (!NumberUtils.isCreatable(numberString)) {
                this.speechletResponse = Response.ERROR;
                break;
            }

            Member member = Info.GUILD.getMemberById(numberString);
            User sender = UserDB.getUser(member);

            Future<Ticket> commissionTicket = new CommissionTicket(sender).create();
            try {
                commissionTicket.get(10000, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                e.printStackTrace();
            }

            SpeechletResponse resp = Response.NEW_TICKED_CREATED;
            resp.setNullableShouldEndSession(true);

            this.speechletResponse = resp;
            break;
    }
}

这是在同一 block 上多次运行的 Ticket#create 方法

public Future<Ticket> create() {
    GuildController guildController = Info.GUILD.getController();
    RequestFuture<Channel> channelRequestFuture = guildController.createTextChannel(ticketType.name().toLowerCase() + "-" + creator.getName() + "-" + id.value()).submit();
    try {
        Channel channel = channelRequestFuture.get(10000, TimeUnit.MILLISECONDS);
        ChannelManager channelManager = channel.getManager();
        GuildManager guildManager = channelManager.getGuild().getManager();
        List<Member> members = guildManager.getGuild().getMembers();
        List<Member> admins = new ArrayList<>();

        for (Member member : members) {
            for (Role role : member.getRoles()) {
                if (!role.getName().equalsIgnoreCase(Info.ADMIN_STRING)) continue;
                admins.add(member);
            }
        }

        for (Member member : members) {
            if (member.equals(creator.getMember())) continue;
            channel.createPermissionOverride(member).setDeny(Permission.MESSAGE_READ).queue();
        }


        for (Member admin : admins) {
            if (admin.equals(creator.getMember())) continue;
            channel.createPermissionOverride(admin).setAllow(Permission.MESSAGE_READ).queue();
        }


        BotMessage botMessage = new BotMessage();
        botMessage
                .setTitle("New Ticket! User: " + creator.getName())
                .setColour(Color.CYAN)
                .setDescription("Please enter your full request here! \n" +
                        "Make sure to let us know whether you are looking for a quote/timeframe,\n" +
                        "or have a budget in mind, and we will work around you!\n\n" +
                        "A sales representative will be with you as soon as possible!")
                .send((TextChannel) channel);


        this.textChannel = (TextChannel) channel;

        TicketDB.addTicket(this);

    } catch (Exception e) {
        e.printStackTrace();
    }

    if (!userIsInTicket(creator)) users.add(creator);
    Future<Ticket> future = ConcurrentUtils.constantFuture(this);
    return future;

}

因此,当运行 Ticket#create 代码时,它会创建一个唯一的新文本 channel ,并向该 channel 发送一条消息。 这一切都很好,但是创建 channel 后,我再次调用 lambda 函数,因此它是“温暖的”,并且它按预期创建了一个新的唯一文本 channel ,但它还在创建的 channel 中发送该消息之前由于某种未知原因又两次。如果我能得到关于原因的帮助,我将不胜感激。谢谢

https://gyazo.com/2432b101a051ce2dc6521e939d8a8690

最佳答案

我认为您问题的核心是,某些变量( channel )位于处理程序函数之外。

AWS Lambda 只是一个 Docker 容器。容器有时会重新启动......但通常一旦它启动并初始化,当您调用“热”lambda 时唯一发生的事情是您的处理程序函数在现有和正在运行的内部被调用(由某些外部 AWS 事物)容器...

因此,任何位于处理函数之外且仅在代码首次初始化时才被调用的内容,并将在后续调用中保留其初始值。

试试这个(Python 示例):

from datetime import datetime

now = str(datetime.now())

def lambda_handler(event, context):
    return now

这段代码将存在于名为lambda_function.py的模块中。当您第一次调用 lambda 时,将启动带有 Python 解释器的 Docker 容器,该容器将加载您的 lambda_function 模块并调用 lambda_handler() 函数。 p>

但是,当您第二次调用该函数时,该模块已经被加载。因此,now 变量已经被初始化并具有之前的值。对 lambda_handler() 的后续调用(如果需要,也可以称为“lambda 函数调用”)将仅传递模块首次初始化时创建的相同值。

关于java - AWS Lambda 热函数重新发送代码,如何停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52906096/

相关文章:

java - 迭代以在索引处查找 Map 条目?

java - 对使用 kstream 连接的 kafka 拓扑进行单元测试

java - LocalTime.MIDNIGHT 与 LocalTime.MIN - 有什么区别吗?

hadoop - EMR作业中的自定义RecordReader

amazon-web-services - 如何查看 AWS 中每个实例上个月的 (RDS) 成本?

python - 更新 DynamoDB 时出现客户端错误?

java - 清理ActiveMQ对象

java - AWS 源代码错误?

node.js - 使用 Lambda Node 从 S3 上的文件在 S3 上创建一个 zip 文件

amazon-web-services - 适用于OPTIONS的AWS API Gateway CORS正常,执行POST失败