所以我的代码执行了多次,几乎就像它在代码中返回并以某种方式重新执行一样...
此代码在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;
}
}
这是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代码运行时,它将创建一个唯一的新文本通道,并向该通道发送一条消息。 一切都很好,但是在创建通道之后,我再次调用了lambda函数,因此它是“暖和的”,并且按预期方式创建了一个新的唯一文本通道,但是它还在创建的通道中发送了该消息之前由于未知原因又两次。如果我能得到为什么的帮助,将不胜感激。谢谢
答案 0 :(得分:1)
我相信您问题的核心是某些变量(通道)存在于处理程序函数之外。
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()
函数。
但是,当您第二次调用该函数时,该模块已经加载。因此now
变量已经被初始化,并且它是先前的值。随后对lambda_handler()
的调用(如果需要,也可以调用“ lambda函数调用”)将传递与第一次初始化模块时创建的值相同的值。