AWS lambda 实例在 xstate 调用承诺时关闭
Posted
技术标签:
【中文标题】AWS lambda 实例在 xstate 调用承诺时关闭【英文标题】:AWS lambda instance shuts down while xstate invoke promise 【发布时间】:2020-06-20 00:58:27 【问题描述】:我有一个 lambda 函数,它使用 xstate 顺序执行某些任务,其中一个步骤是将数据保存到 dynamo db。但是我的 lambda 在执行以下行时立即结束执行。
const response = await new DynamoDB.DocumentClient().put(params).promise();
我的代码:
import Handler from "aws-lambda";
import interpret from 'xstate';
import Machine from "xstate";
import PutItemInput from "aws-sdk/clients/dynamodb";
import DynamoDB from "aws-sdk";
export const recordProcessor: Handler = async (event) =>
console.log('records size----->', event.Records.length);
for (const record of event.Records)
const body = JSON.parse(record.body);
console.log('body ----->', body);
interpret(Machine(id:'test',
context:body,
initial: 'start',
states:
start:
invoke:
src: context => initiate(context),
onDone:
target: 'success'
,
success:
type: 'final'
)).onTransition(state =>
if (state.changed)
console.log('state ----> ', state.value);
).onDone(() => console.log('done--->')).start();
async function initiate(context: any)
console.log('DbDynamoImpl ::: insert ::: start :::');
let params: PutItemInput =
TableName: 'test',
Item: context
;
try
const response = await new DynamoDB.DocumentClient().put(params).promise();
console.log('DbDynamoImpl ::: insert ::: response :::', response);
return true;
catch (e)
console.log("DynamoDb insert error", e);
return false;
;
【问题讨论】:
不看完整代码很难说。 添加了测试代码,因为我无法分享我的整个代码。 由于项目时间表的原因,我不得不将实现从 xstate 更改为责任链设计模式,并且还没有时间让 Greg 和 Iko 进行检查。但是会尽快检查并更新...如果可行,其他人也可以免费投票。 【参考方案1】:将async
添加到您的函数中,然后再次测试。
exports.handler = async (event, context) =>
return ...
【讨论】:
我认为您需要为任何异步函数调用添加await
。我的意思是initiate
【参考方案2】:
您在点击return
语句之前解决了 Promise。您可以尝试resolve
Promise
使用您需要返回的值吗?然后它将使用这些值转到 onDone 块。还有try
和catch
块在这里是多余的,因为xstate
中的service
会自动为你处理。
只需在服务调用语句中返回承诺,因为它需要是一个返回Promise
的函数
function initiate(context: any)
console.log('DbDynamoImpl ::: insert ::: start :::');
let params: PutItemInput =
TableName: 'test',
Item: context,
;
return new DynamoDB.DocumentClient().put(params).promise();
然后在你的onDone
块中你可以console.log('DbDynamoImpl ::: insert ::: response :::', response);
onDone:
target: 'success',
actions: (ctx, e) => console.log('DbDynamoImpl ::: insert ::: response :::', e),
【讨论】:
【参考方案3】:将机器解释和交互包装成一个 Promise 允许您等待状态机达到最终状态。
大概是这样的
export const recordProcessor: Handler = async (event) =>
console.log('records size----->', event.Records.length);
for (const record of event.Records)
const body = JSON.parse(record.body);
console.log('body ----->', body);
await setupMachine(...);
...
function setupMachine(...)
return new Promise((resolve, reject) =>
interpret(Machine(id:'test',
context:body,
initial: 'start',
states:
start:
invoke:
src: context => initiate(context),
onDone:
target: 'success'
,
success:
type: 'final'
)).onTransition(state =>
if (state.changed)
console.log('state ----> ', state.value);
)
.onDone(() => console.log('done--->'); return resolve())
.onStop(() => reject());
.start();
);
【讨论】:
以上是关于AWS lambda 实例在 xstate 调用承诺时关闭的主要内容,如果未能解决你的问题,请参考以下文章