Lambda 作为泄漏状态机?
Lambda as a leaky state machine?
我有一个涉及 OAuth 1 交互的微服务。我发现自己处于这样一种情况,即具有完全相同起始状态的 Lambda 函数的两个 运行 具有非常不同的结果(其中状态被认为是传入的 "event"、环境变量和 "stageParameters" 来自 API 网关)。
这是一个显示两个背靠背 运行s 的 Cloudwatch 日志:
您可以看到,虽然起始状态相同,但执行路径变化非常快。在第二种情况(失败情况)中,您会看到日志条目 "Auth state changed: null" ...这确实很奇怪,因为实际上这是在 before 甚至第一行代码中记录的的 "handler" 被执行。这是函数处理程序的开头:
export const handler = (event, context, cb) => {
console.log('EVENT:\n', JSON.stringify(event, null, 2));
那么这个过早的日志条目是从哪里来的呢?好吧,我们必须假设它不知何故是先前处决遗留下来的。让我演示一下……它实际上是一个在先前执行中设置的事件监听器。此函数与 Firebase 数据库交互,第一次连接时会设置以下内容:
auth.signInWithEmailAndPassword(username, password)
.then((result) => {
auth.onAuthStateChanged(this.watchAuthState);
其中 watchAuthState
函数很简单:
watchAuthState(user) {
console.log(`Auth state changed:\n`, JSON.stringify(user, null, 2));
}
这似乎意味着当我第二次 运行 数据库时,我已经 "initialized" 使用了 Firebase 数据库,但显然身份验证已失效。我的首要目标是回到预测状态模型并让它每次都完全相同地执行。
如果有偷偷摸摸的方法以资源有用的方式重用 Lambda 执行之间的缓存状态,那么我想这也会很有趣,但前提是我们可以在实现预测状态机的同时做到这一点。
关于日志顺序,请查看每行开头每个时间戳后的 ID。我相信这是调用 ID。在您用橙色突出显示的两行中,它们来自函数的不同调用。 EVENT
日志是从 ID 以 754ee
结尾的调用中记录的第一行。 Auth state changed: null
行是来自早期函数调用的日志条目,调用 ID 以 c40d5
.
结尾
您似乎在调用结束时将 auth 状态设置为 null,但 Firebase 连接是全局的,因此第二次函数调用认为 Firebase 连接已经初始化,但随后它抛出错误,因为身份验证被清零了。
My number one aim is to just get back to a predictive state model and
have it execute precisely the same each time.
那么你需要注意Lambda container reuse,不要使用任何全局变量。
我有一个涉及 OAuth 1 交互的微服务。我发现自己处于这样一种情况,即具有完全相同起始状态的 Lambda 函数的两个 运行 具有非常不同的结果(其中状态被认为是传入的 "event"、环境变量和 "stageParameters" 来自 API 网关)。
这是一个显示两个背靠背 运行s 的 Cloudwatch 日志:
您可以看到,虽然起始状态相同,但执行路径变化非常快。在第二种情况(失败情况)中,您会看到日志条目 "Auth state changed: null" ...这确实很奇怪,因为实际上这是在 before 甚至第一行代码中记录的的 "handler" 被执行。这是函数处理程序的开头:
export const handler = (event, context, cb) => {
console.log('EVENT:\n', JSON.stringify(event, null, 2));
那么这个过早的日志条目是从哪里来的呢?好吧,我们必须假设它不知何故是先前处决遗留下来的。让我演示一下……它实际上是一个在先前执行中设置的事件监听器。此函数与 Firebase 数据库交互,第一次连接时会设置以下内容:
auth.signInWithEmailAndPassword(username, password)
.then((result) => {
auth.onAuthStateChanged(this.watchAuthState);
其中 watchAuthState
函数很简单:
watchAuthState(user) {
console.log(`Auth state changed:\n`, JSON.stringify(user, null, 2));
}
这似乎意味着当我第二次 运行 数据库时,我已经 "initialized" 使用了 Firebase 数据库,但显然身份验证已失效。我的首要目标是回到预测状态模型并让它每次都完全相同地执行。
如果有偷偷摸摸的方法以资源有用的方式重用 Lambda 执行之间的缓存状态,那么我想这也会很有趣,但前提是我们可以在实现预测状态机的同时做到这一点。
关于日志顺序,请查看每行开头每个时间戳后的 ID。我相信这是调用 ID。在您用橙色突出显示的两行中,它们来自函数的不同调用。 EVENT
日志是从 ID 以 754ee
结尾的调用中记录的第一行。 Auth state changed: null
行是来自早期函数调用的日志条目,调用 ID 以 c40d5
.
您似乎在调用结束时将 auth 状态设置为 null,但 Firebase 连接是全局的,因此第二次函数调用认为 Firebase 连接已经初始化,但随后它抛出错误,因为身份验证被清零了。
My number one aim is to just get back to a predictive state model and have it execute precisely the same each time.
那么你需要注意Lambda container reuse,不要使用任何全局变量。