挂起等待 s3.listObjects
Hangs on await s3.listObjects
我有一个事件会触发 lambda 代码,该代码会尝试列出一个存储桶中的所有对象,然后将它们复制到另一个存储桶。
通过事件调用处理程序的代码
const cfnHandlerWrapper = async (event, handler) => {
let resultPromise;
try {
handler(event).then(function() {
console.log(`Successfully copied over all artifacts`);
resultPromise = sendSuccess(event);
}).catch(function(error) {
console.log(`Failed copying over all artifacts: ${error}`);
throw error;
});
} catch (e) {
console.log('ERROR RUNNING HANDLER:');
console.log(e);
resultPromise = sendFailure(e.message || 'Something went wrong', event);
}
return resultPromise;
};
处理复制的代码
const copyHandler = async (event) => {
console.log('Running Agent artifacts copy handler');
const {RequestType, ResourceProperties} = event;
const {DestBucket, SrcBucket, AdditionalArtifactsPath} = ResourceProperties;
if (RequestType === 'Create' || RequestType === 'Update') {
const srcLocation = [SrcBucket, AdditionalArtifactsPath].join('/');
const batsAdditionalArtifactsParams = {
Bucket: SrcBucket,
Delimiter: '',
Prefix: `${AdditionalArtifactsPath}/`
};
let copyPromises = [];
console.log("about to await s3.listObjects()...");
let listObjectsResult;
try {
listObjectsResult = await s3.listObjects(batsAdditionalArtifactsParams).promise();
} catch(err) {
console.log(`Failed to list objects for ${srcLocation}, err: ${err}`);
throw err;
}
console.log(`finished waiting for listObjects. listObjectsResult: ${listObjectsResult}`);
console.log(`Successfully listed objects in ${srcLocation}. Attempting to copy all artifacts to ${DestBucket}`);
listObjectsResult.Contents.forEach((object) => {
console.log(`parsing object ${object}`);
let keyParts = object.Key.split('/');
let fileKey = keyParts.pop();
let destKey = fileKey.includes(agentBootstrapScript) ? `${agentBootstrapScriptsFolder}/${agentBootstrapScript}` : fileKey; // Adhere to bootstrap folder structure
let copyParams = {
Bucket: DestBucket,
CopySource: `${srcLocation}/${fileKey}`,
Key: destKey
};
console.log("pushing copy promise");
copyPromises.push(s3.copyObject(copyParams).promise()
.then(function(data) {
console.log(`Successfully copied ${fileKey} from ${srcLocation} to ${DestBucket}! data=${data}`);
}).catch(function(err) {
console.log(`Encountered error while copying ${fileKey} from ${srcLocation} to ${DestBucket}, error: ${err}`);
}));
});
console.log("about to await Promise.all()....");
await Promise.all(copyPromises);
} else {
console.log(`Received event type ${RequestType}, not copying anything`);
}
console.log("returning Promise.resolve()");
return Promise.resolve();
};
这段代码只输出日志信息
about to await s3.listObjects()...
,所以看起来它卡在了等待中:
listObjectsResult = await s3.listObjects(batsAdditionalArtifactsParams).promise();
我想要做的就是等待列出所有对象,承诺复制这些对象,然后使用 Promise.all 等待所有这些复制完成,然后再从此处理程序返回。我在 await 周围放了一个 try/catch ,但它看起来就像永远卡在等待中一样。关于此的任何提示,甚至如何调试这种情况?
你的代码很混乱。您将 async/await 与 Promise.then 混合在一起。通常你会选择一种方式,但绝不会同时选择两种方式。
通过查看您的代码,我 猜测 sendResult
returns 一个 Promise,因为您将其结果分配给了一个名为 resultPromise
的对象但你永远不会等待它。
copyHandler
也是 returns 一个 Promise,但你不等待它(你正在链接 then 调用)但是当它到达 return resultPromise
时,promise 还没有已解决。
对我来说,问题出在您的 cfnHandlerWrapper
函数上。我会更改您发布到的代码:
const cfnHandlerWrapper = async (event, handler) => {
try {
await copyHandler(event)
console.log(`Successfully copied over all artifacts`);
return await sendSuccess(event);
} catch (e) {
console.log('ERROR RUNNING HANDLER:');
console.log(e);
return await sendFailure(e.message || 'Something went wrong', event);
}
};
现在,在您的 forEach
上,您还有另一个问题,因为其中的代码包含也会 运行 异步的承诺,所以当您调用 await Promise.all(copyPromises);
、copyPromises
尚未填充您期望的所有承诺(可能会填充 none)。
我会改用 for of
(下面只有相关代码):
for (const object of listObjectsResult.Contents) {
console.log(`parsing object ${object}`);
let keyParts = object.Key.split('/');
let fileKey = keyParts.pop();
let destKey = fileKey.includes(agentBootstrapScript) ? `${agentBootstrapScriptsFolder}/${agentBootstrapScript}` : fileKey; // Adhere to bootstrap folder structure
let copyParams = {
Bucket: DestBucket,
CopySource: `${srcLocation}/${fileKey}`,
Key: destKey
};
console.log("pushing copy promise");
copyPromises.push(s3.copyObject(copyParams).promise())
}
console.log("about to await Promise.all()....");
await Promise.all(copyPromises)
如果不对这段代码进行测试,很难判断它是否有效,但我不明白为什么它会失败。不管怎样,试着把你的组件分解成更小的部分,看看它到底在哪里失败了。不过,我把我所有的钱都赌在你对待承诺的方式上。
我有一个事件会触发 lambda 代码,该代码会尝试列出一个存储桶中的所有对象,然后将它们复制到另一个存储桶。
通过事件调用处理程序的代码
const cfnHandlerWrapper = async (event, handler) => {
let resultPromise;
try {
handler(event).then(function() {
console.log(`Successfully copied over all artifacts`);
resultPromise = sendSuccess(event);
}).catch(function(error) {
console.log(`Failed copying over all artifacts: ${error}`);
throw error;
});
} catch (e) {
console.log('ERROR RUNNING HANDLER:');
console.log(e);
resultPromise = sendFailure(e.message || 'Something went wrong', event);
}
return resultPromise;
};
处理复制的代码
const copyHandler = async (event) => {
console.log('Running Agent artifacts copy handler');
const {RequestType, ResourceProperties} = event;
const {DestBucket, SrcBucket, AdditionalArtifactsPath} = ResourceProperties;
if (RequestType === 'Create' || RequestType === 'Update') {
const srcLocation = [SrcBucket, AdditionalArtifactsPath].join('/');
const batsAdditionalArtifactsParams = {
Bucket: SrcBucket,
Delimiter: '',
Prefix: `${AdditionalArtifactsPath}/`
};
let copyPromises = [];
console.log("about to await s3.listObjects()...");
let listObjectsResult;
try {
listObjectsResult = await s3.listObjects(batsAdditionalArtifactsParams).promise();
} catch(err) {
console.log(`Failed to list objects for ${srcLocation}, err: ${err}`);
throw err;
}
console.log(`finished waiting for listObjects. listObjectsResult: ${listObjectsResult}`);
console.log(`Successfully listed objects in ${srcLocation}. Attempting to copy all artifacts to ${DestBucket}`);
listObjectsResult.Contents.forEach((object) => {
console.log(`parsing object ${object}`);
let keyParts = object.Key.split('/');
let fileKey = keyParts.pop();
let destKey = fileKey.includes(agentBootstrapScript) ? `${agentBootstrapScriptsFolder}/${agentBootstrapScript}` : fileKey; // Adhere to bootstrap folder structure
let copyParams = {
Bucket: DestBucket,
CopySource: `${srcLocation}/${fileKey}`,
Key: destKey
};
console.log("pushing copy promise");
copyPromises.push(s3.copyObject(copyParams).promise()
.then(function(data) {
console.log(`Successfully copied ${fileKey} from ${srcLocation} to ${DestBucket}! data=${data}`);
}).catch(function(err) {
console.log(`Encountered error while copying ${fileKey} from ${srcLocation} to ${DestBucket}, error: ${err}`);
}));
});
console.log("about to await Promise.all()....");
await Promise.all(copyPromises);
} else {
console.log(`Received event type ${RequestType}, not copying anything`);
}
console.log("returning Promise.resolve()");
return Promise.resolve();
};
这段代码只输出日志信息
about to await s3.listObjects()...
,所以看起来它卡在了等待中:
listObjectsResult = await s3.listObjects(batsAdditionalArtifactsParams).promise();
我想要做的就是等待列出所有对象,承诺复制这些对象,然后使用 Promise.all 等待所有这些复制完成,然后再从此处理程序返回。我在 await 周围放了一个 try/catch ,但它看起来就像永远卡在等待中一样。关于此的任何提示,甚至如何调试这种情况?
你的代码很混乱。您将 async/await 与 Promise.then 混合在一起。通常你会选择一种方式,但绝不会同时选择两种方式。
通过查看您的代码,我 猜测 sendResult
returns 一个 Promise,因为您将其结果分配给了一个名为 resultPromise
的对象但你永远不会等待它。
copyHandler
也是 returns 一个 Promise,但你不等待它(你正在链接 then 调用)但是当它到达 return resultPromise
时,promise 还没有已解决。
对我来说,问题出在您的 cfnHandlerWrapper
函数上。我会更改您发布到的代码:
const cfnHandlerWrapper = async (event, handler) => {
try {
await copyHandler(event)
console.log(`Successfully copied over all artifacts`);
return await sendSuccess(event);
} catch (e) {
console.log('ERROR RUNNING HANDLER:');
console.log(e);
return await sendFailure(e.message || 'Something went wrong', event);
}
};
现在,在您的 forEach
上,您还有另一个问题,因为其中的代码包含也会 运行 异步的承诺,所以当您调用 await Promise.all(copyPromises);
、copyPromises
尚未填充您期望的所有承诺(可能会填充 none)。
我会改用 for of
(下面只有相关代码):
for (const object of listObjectsResult.Contents) {
console.log(`parsing object ${object}`);
let keyParts = object.Key.split('/');
let fileKey = keyParts.pop();
let destKey = fileKey.includes(agentBootstrapScript) ? `${agentBootstrapScriptsFolder}/${agentBootstrapScript}` : fileKey; // Adhere to bootstrap folder structure
let copyParams = {
Bucket: DestBucket,
CopySource: `${srcLocation}/${fileKey}`,
Key: destKey
};
console.log("pushing copy promise");
copyPromises.push(s3.copyObject(copyParams).promise())
}
console.log("about to await Promise.all()....");
await Promise.all(copyPromises)
如果不对这段代码进行测试,很难判断它是否有效,但我不明白为什么它会失败。不管怎样,试着把你的组件分解成更小的部分,看看它到底在哪里失败了。不过,我把我所有的钱都赌在你对待承诺的方式上。