如果项未退出,请插入DynamoDB
我正在使用aws-rekognition对流视频进行出勤检查,当识别出一个人时,lambda应该将其写入DynamoDB。 insertDynamo()
单独工作正常(当我不将其称为函数时),但是当我将其放入函数中时,它不会写入DynamoDB表。对哪里做错有任何想法吗?
var AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var hour = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
exports.handler = async (event, context) => {
//console.log('Received event:', JSON.stringify(event, null, 2));
event.Records.forEach((record) => {
// Kinesis data is base64 encoded so decode here
const load = new Buffer(record.kinesis.data, 'base64').toString('ascii');
const payload = JSON.parse(load);
if(payload.FaceSearchResponse != null)
{
payload.FaceSearchResponse.forEach((face) => {
if(face.MatchedFaces != null &&
Object.keys(face.MatchedFaces).length > 0)
{
var id = JSON.stringify(face.MatchedFaces[0].Face.ExternalImageId, null, 4);
//this is hard code it ---needs to split string from kinesis(id)
insertDynamo(date,hour,'0001');
}
else
{
//do nothing
}
});
}
});
return `Successfully processed ${event.Records.length} records.`;
};
var insertDynamo = function(date,hour,id){
exports.handler = async (event,context) => {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
const params = {
TableName: "users",
Item:{
badgeNumber: id,
assistance:{
date:date,
hour:hour
}
},
ConditionExpression: 'attribute_not_exists(badgenumber)'
};
try {
const data = await documentClient.put(params).promise();
responseBody = JSON.stringify(data);
statusCode = 201;
} catch (err) {
responseBody = `Unable to put product: ${err}`;
statusCode = 403;
}
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json"
},
body:responseBody
}
return response
}
};
回答如下:您的lambda函数在被调用时将立即完成,因为您使用.forEach
遍历了所有记录。这意味着您所有插入DynamoDB的请求都将在完成yobs之前被取消。
我为您的案件提供2种解决方案:
等待,直到清除lambda回调堆栈
只需在您的lambda函数前添加“ config”行
context.callbackWaitsForEmptyEventLoop = true;
使用老式循环代替
forEach
(推荐)。forEach
使用回调样式来解决每个项目,然后使用async/await
关键字将无法按预期工作。
var AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var hour = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
exports.handler = async (event, context) => {
//console.log('Received event:', JSON.stringify(event, null, 2));
for (const record of event.Records) { // for of instead of forEach
const load = new Buffer(record.kinesis.data, 'base64').toString('ascii');
const payload = JSON.parse(load);
if (payload.FaceSearchResponse != null) {
for (const face of payload.FaceSearchResponse) { // for of instead of forEach
if (face.MatchedFaces != null &&
Object.keys(face.MatchedFaces).length > 0) {
var id = JSON.stringify(face.MatchedFaces[0].Face.ExternalImageId, null, 4);
//this is hard code it ---needs to split string from kinesis(id)
await insertDynamo(date, hour, '0001'); // wait until task finish then solve next item
}
else {
//do nothing
}
}
}
}
return `Successfully processed ${event.Records.length} records.`;
};
var insertDynamo = function (date, hour, id) {
// What is this?????????
// exports.handler = async (event, context) => {
// }
const documentClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: "users",
Item: {
badgeNumber: id,
assistance: {
date: date,
hour: hour
}
},
ConditionExpression: 'attribute_not_exists(badgenumber)'
};
return documentClient.put(params).promise(); // enough for us
};