Javascript Node.js/AWS Lambda在发送SNS推送之前结束
也许擅长Node.js的人可以解决这个问题。 在Amazon Web服务上编写和测试我的代码时,我注意到Lambda有时会在SNS发布之前终止该函数。我认为问题可能正在发生,因为“context.done”很早就被调用了。但从逻辑上讲,这种情况不应该发生。重要信息:代码工作正常!(除了我前面提到的那件事) 代码的基本思想是:只要DynamoDB中的条目发生变化,Lambda就会做出反应,并通过SNS推送通知“所有者” 谢谢你的帮助Javascript Node.js/AWS Lambda在发送SNS推送之前结束,javascript,node.js,amazon-web-services,aws-lambda,Javascript,Node.js,Amazon Web Services,Aws Lambda,也许擅长Node.js的人可以解决这个问题。 在Amazon Web服务上编写和测试我的代码时,我注意到Lambda有时会在SNS发布之前终止该函数。我认为问题可能正在发生,因为“context.done”很早就被调用了。但从逻辑上讲,这种情况不应该发生。重要信息:代码工作正常!(除了我前面提到的那件事) 代码的基本思想是:只要DynamoDB中的条目发生变化,Lambda就会做出反应,并通过SNS推送通知“所有者” 谢谢你的帮助 此代码正在Lambda实例上运行 console.log('L
此代码正在Lambda实例上运行
console.log('Loading function');
var aws = require('aws-sdk');
var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();
exports.handler = function(event, context){
var target = null;
var status = null;
event.Records.forEach(function(record){
console.log("Function Invoked");
console.log("Function Event: "+record.eventName);
if(record.eventName === "MODIFY")
{
db_record_exists(record, function(r) {
if (r) {
if(r.handle == "true"){
creator = r.creator;
participant = r.participant;
creator = JSON.stringify(creator);
status = JSON.stringify(record.dynamodb.NewImage.status.S);
creator = creator.replace(/"/g, "");
status = status.replace(/"/g, "");
participant = JSON.stringify(record.dynamodb.NewImage.participant.S);
participant = participant.replace(/"/g, "");
console.log("creator: "+ creator);
console.log("status: "+ status);
console.log("participant is: "+ participant);
getCredentialsMovement(creator,participant,function(response){
console.log("RESPONSE: "+ response);
sendSNSmovement(response, status, context);
});
}else{
context.done();
}
}
});
}else if(record.eventName == "INSERT"){
db_record_exists(record, function(r) {
if (r) {
if(r.handle == "true"){
creator = r.creator;
participant = r.participant;
creator = JSON.stringify(creator);
status = JSON.stringify(record.dynamodb.NewImage.status.S);
creator = creator.replace(/"/g, "");
status = status.replace(/"/g, "");
participant = JSON.stringify(record.dynamodb.NewImage.participant.S);
participant = participant.replace(/"/g, "");
console.log("creator: "+ creator);
console.log("status: "+ status);
console.log("participant is: "+ participant);
getCredentialsInvitation(creator,participant,function(response){
console.log("RESPONSE: "+ response);
sendSNSinvitation(response, context);
});
}else{
context.done();
}
} else context.done();
});
}else{
context.done();
}
}
);
};
function db_record_exists(record, callback){
var users = {};
users.creator = record.dynamodb.NewImage.creator.S;
users.participant = record.dynamodb.NewImage.participant.S;
if(users.creator != users.participant){
users.handle = "true";
}else{
users.handle = "false";
}
callback(users);
}
function shutdown(context){
context.done();
}
function sendSNSmovement(creator_information, status, context){
var sns = new aws.SNS();
var payload_negative = creator_information.name + " has declined your event!";
var payload_positive = creator_information.name + " has accepted your event!";
//var payload_positive = "Positive";
var payload_accepted = {
"GCM": "{ \"data\": { \"message\": \"Your event has been accepted!!\"} }"
};
var payload_declined = { "GCM": "{ \"data\": { \"message\": \"Your event has been declined!\" } }" };
// console.log("Standart Message as JSON: "+ payload_declined.GCM);
payload_declined.GCM = "{ \"data\": { \"message\": \""+payload_negative+"\" } }";
payload_accepted.GCM = "{ \"data\": { \"message\": \""+payload_positive+"\" } }";
// console.log("Standart Message as JSON: "+ payload_declined.GCM);
// console.log("Standart Message as String: "+ JSON.stringify(payload_declined));
payload_accepted = JSON.stringify(payload_accepted);
payload_declined = JSON.stringify(payload_declined);
var payload;
if(status == "true"){
payload = payload_accepted;
}else{
payload = payload_declined;
}
var params = {
TargetArn: creator_information.arn,
MessageStructure: 'json',
Message: payload
};
sns.publish(
params, function(err, data) {
if (err) {
console.log(err.stack);
// Notify Lambda that we are finished, but with errors
context.done(err, 'Brians Function Finished with Errors!');
}else{
console.log('push sent');
console.log(data);
// Notify Lambda that we are finished
context.done();
}
});
}
function sendSNSinvitation(creator_information,context){
var sns = new aws.SNS();
var payload_message = creator_information.name + " has invited you to an event!";
var payload = {
"GCM": "{ \"data\": { \"message\": \"Your event has been accepted!!\"} }"
};
payload.GCM = "{ \"data\": { \"message\": \""+payload_message+"\" } }";
payload = JSON.stringify(payload);
var params = {
TargetArn: creator_information.arn,
MessageStructure: 'json',
Message: payload
};
sns.publish(
params, function(err, data) {
if (err) {
console.log(err.stack);
// Notify Lambda that we are finished, but with errors
context.done(err, 'Brians Function Finished with Errors!');
}else{
console.log('push sent');
console.log(data);
// Notify Lambda that we are finished
context.done();
}
});
}
function getCredentialsMovement(creator,participant,callback) {
var params_name = {
TableName : "users",
Key : {
"id" : participant
},
ProjectionExpression: 'person_name'
};
var params_arn = {
TableName : "users",
Key : {
"id" : creator
},
ProjectionExpression: 'arn'
};
dynamo.getItem(params_name, function(err, data) {
var response = {};
if (err) {
console.log(err);
return err;
}
else {
console.log("creators name is: "+data.Item.person_name);
response.name = data.Item.person_name;
dynamo.getItem(params_arn, function(err, data) {
if (err) {
console.log(err);
return err;
}
else {
console.log(data.Item.arn);
response.arn = data.Item.arn;
return callback(response);
}
});
}
});
}
function getCredentialsInvitation(creator,participant,callback) {
var params_name = {
TableName : "users",
Key : {
"id" : creator
},
ProjectionExpression: 'person_name'
};
var params_arn = {
TableName : "users",
Key : {
"id" : participant
},
ProjectionExpression: 'arn'
};
dynamo.getItem(params_name, function(err, data) {
var response = {};
if (err) {
console.log(err);
return err;
}
else {
console.log("creators name is: "+data.Item.person_name);
response.name = data.Item.person_name;
dynamo.getItem(params_arn, function(err, data) {
if (err) {
console.log(err);
return err;
}
else {
console.log(data.Item.arn);
response.arn = data.Item.arn;
return callback(response);
}
});
}
});
}
我不知道您的代码到底出了什么问题,但我有一些调试建议:
context.done()
的9个调用,它们分布在多个函数中。您应该将其减少到一个或两个(成功/错误)。不要让每个函数调用context.done()
,而是让它们使用回调将状态返回给顶级处理程序假设此代码有两个修改事件,对于第一个db_记录,exist函数返回r.handle=“true”,第二个返回false。第一个将继续异步调用getCredentials(dynamo.getItem)。同时,将处理第二条记录并调用context.done(),从而在不等待dynamo响应的情况下结束lambda函数谢谢您的回答。这些东西我都试过了。Amazon的一位工程师告诉我,如果我使用多个“context.done()”调用,只要它们在逻辑上是分开的,就没有关系。你还有什么进一步的建议吗?如果只有一个语句,那么验证逻辑就更容易了。尝试使用MODIFY运行100次,使用INSERT事件运行100次,并计算每个路径的成功率。这可能会帮助您了解问题的类型,以及应该在代码中查找的位置。