[英]Node.js AWS Lambda not waiting for anything
我已经尝试了所有建议的解决方案并查看了每个类似的问题,但没有解决我的问题。 这个脚本在我的本地机器上工作得很好。 Lambda 的问题在于它完全跳过超时并等待。 而我的本地机器实际上在等待。
我的索引文件如下所示:
import { getData } from './src/EC2Scripts/taskScripts/otherLogic.js';
async function handler(event) {
await getData();
const response = {
statusCode: 200,
body: JSON.stringify("Not waiting."),
};
return response;
}
export { handler };
这是其他逻辑 class:
import fetch from "node-fetch";
import { PoolConnection } from '../common/classes/PoolConnection.js';
async function getData() {
return new Promise(async (resolve, reject) => {
let pool = PoolConnection.getInstance();
let currentResponse = await fetch(
"dummyURL"
);
let currentData = await currentResponse.json();
pool.uploadCoins(currentData).then((result) => {
pool.endConnection().then((end) => { resolve() });
});
});
}
export { getData };
这是 PoolConnection class:
import pg from "pg";
import fetch from "node-fetch";
import { getCurrentDateTime } from "../dateTime.js";
class PoolConnection {
// DO NOT CALL THIS CONSTRUCTOR, CALL THE GETINSTANCE() METHOD
constructor() {
if (!PoolConnection.instance) {
PoolConnection.instance = this;
this.config = {
user: "user",
password: "password",
database: "postgres",
host: "host",
port: 5432,
max: 100,
connectionTimeoutMillis: 30000,
idleTimeoutMillis: 30000
};
this.pool = this.establishConnection(1).catch((error) => { });
}
}
static getInstance() {
if (PoolConnection.instance) {
return PoolConnection.instance;
}
PoolConnection.instance = new PoolConnection();
return PoolConnection.instance;
}
async connect() {
return new Promise((resolve, reject) => {
const poolPromise = new pg.Pool(this.config);
poolPromise.connect()
.then(pool => {
console.log(getCurrentDateTime() + " ----- Connection to article database successful.");
resolve(pool);
})
.catch(err => {
console.error(getCurrentDateTime() + " ----- ERROR CONNECTING TO ARTICLE DATABASE :: " + err);
reject(err);
});
});
}
async establishConnection(attempts) {
return new Promise((resolve, reject) => {
if (attempts > 5) {
console.log(getCurrentDateTime() + " ---- Connection unsuccessful to database, maximum number of attempts reached.");
reject("ERROR");
}
this.connect().then(pool => {
resolve(pool);
}).catch(err => {
console.error(getCurrentDateTime() + " RETRYING CONNECTION TO DATABASE ATTEMPT #" + attempts);
attempts++;
// try again in 3 seconds
setTimeout(() => { this.establishConnection(attempts) }, 3000);
});
})
}
// Connection has to be terminated gracefully or else script will hang.
async endConnection() {
return new Promise((resolve, reject) => {
this.pool.then(connection => connection.end(() => console.log(getCurrentDateTime() + " ---- Connection to database successfully terminated.")));
});
}
async uploadData(data) {
return new Promise((resolve, reject) => {
this.pool.then(async (poolInstance) => {
for(const entry of data) {
let getMoreData = await fetch (
"dummyUrl2" + entry
);
const result = poolInstance.query("INSERT INTO table(data) VALUES ($1)",
[entry['getMoreData']]);
}
resolve();
});
});
}
}
export { PoolConnection }
它试图在我做任何事情之前关闭连接。 这是错误:
> START RequestId: 5aa4984b-d57f-4d69-84a3-005a6c590c0f Version: $LATEST
> 2022-05-03T14:48:11.625Z 5aa4984b-d57f-4d69-84a3-005a6c590c0f INFO 2022-5-3
> **** 14:48:11 ----- Connection to article database successful. 2022-05-03T14:48:12.946Z 5aa4984b-d57f-4d69-84a3-005a6c590c0f INFO 2022-5-3
> **** 14:48:12 ---- Connection to database successfully terminated. 2022-05-03T14:48:14.146Z 5aa4984b-d57f-4d69-84a3-005a6c590c0f ERROR Unhandled Promise Rejection
> {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"Error:
> Client was closed and is not
> queryable","reason":{"errorType":"Error","errorMessage":"Client was
> closed and is not queryable","stack":["Error: Client was closed and is
> not queryable"," at
> /var/task/node_modules/pg/lib/client.js:570:27"," at
> processTicksAndRejections
> (internal/process/task_queues.js:77:11)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection:
> Error: Client was closed and is not queryable"," at
> process.<anonymous> (/var/runtime/index.js:35:15)"," at
> process.emit (events.js:400:28)"," at processPromiseRejections
> (internal/process/promises.js:245:33)"," at
> processTicksAndRejections (internal/process/task_queues.js:96:32)"]}
> END RequestId: 5aa4984b-d57f-4d69-84a3-005a6c590c0f REPORT RequestId:
> 5aa4984b-d57f-4d69-84a3-005a6c590c0f Duration: 2985.31 ms Billed
> Duration: 2986 ms Memory Size: 128 MB Max Memory Used: 75 MB Init
> Duration: 267.75 ms
我试过转换所有内容以返回一个新的 Promise,然后使用 .then(),但这实际上使程序以某种方式运行得更快。 我试过使用 Promise.all().then()。 我试过将 setTimeout() 移动到 index.js 中的处理程序中,但这也没有用。 我试过在 pool.uploadData() 之后使用 then()。 我也试过从方法处理程序中删除异步。
我现在没主意了。 我已经重构并尝试以我见过的所有方式实现此代码,但没有任何效果。
没有错误或未捕获的异常,它只是没有等待任何东西。
Lambda 使用的是 NodeJS 版本 14.x
编辑:添加池连接 class 并更新类以更清楚地显示我尝试过的内容。
虽然getData()
被标记为async
,但它不返回任何明确的承诺,因此它返回一个Promise<void>
立即解析(到undefined
)。
您需要返回一个明确的Promise
,它在运行您的业务逻辑后解析/拒绝,以使 Lambda 实际上等待处理完成。
如果您的代码执行异步任务,请返回 promise以确保它完成运行。 当您解决或拒绝 promise 时,Lambda 会将响应或错误发送给调用者。
例如,这将返回Promise
,它会在 5 秒后解析,使 Lambda 在返回响应之前等待:
async function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), 5000)
});
}
async function handler(event) {
await getData();
const response = {
statusCode: 200,
body: JSON.stringify("Waiting 5 seconds..."),
};
return response;
}
export { handler };
START RequestId: 0ee7693e-8d6a-4c3f-b23e-119377e633e3 Version: $LATEST
END RequestId: 0ee7693e-8d6a-4c3f-b23e-119377e633e3
REPORT RequestId: 0ee7693e-8d6a-4c3f-b23e-119377e633e3 Duration: 5009.05 ms Billed Duration: 5010 ms Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 224.62 ms
我添加这个是因为我能够弄清楚出了什么问题。 在以前的答案/评论的帮助下,我重新格式化了我的代码,所以如果其他人遇到类似的问题,希望这会有所帮助。
索引.js:
import { getData } from './src/EC2Scripts/taskScripts/otherLogic.js';
async function handler(event) {
await getData();
const response = {
statusCode: 200,
body: JSON.stringify("Now waiting."),
};
return response;
}
export { handler };
其他逻辑 class:
import fetch from "node-fetch";
import { PoolConnection } from '../common/classes/PoolConnection.js';
async function getData() {
return new Promise(async (resolve, reject) => {
let pool = await PoolConnection.getInstance();
let currentResponse = await fetch(
"dummyURL"
);
let currentData = await currentResponse.json();
await pool.uploadData(currentData);
await pool.endConnection();
resolve();
});
}
export { getData };
池连接 class:
import pg from "pg";
import fetch from "node-fetch";
import { getCurrentDateTime } from "../dateTime.js";
class PoolConnection {
// DO NOT CALL THIS CONSTRUCTOR, CALL THE GETINSTANCE() METHOD
constructor() {
if (!PoolConnection.instance) {
PoolConnection.instance = this;
this.config = {
user: "user",
password: "password",
database: "postgres",
host: "host",
port: 5432,
max: 100,
connectionTimeoutMillis: 30000,
idleTimeoutMillis: 30000
};
this.pool = new pg.Pool(this.config);
}
}
static async getInstance() {
return new Promise(async (resolve, reject) => {
if (PoolConnection.instance) {
return PoolConnection.instance;
}
PoolConnection.instance = new PoolConnection();
resolve(PoolConnection.instance);
});
}
// Connection has to be terminated gracefully or else script will hang.
async endConnection() {
return new Promise(async (resolve, reject) => {
await this.pool.end(() => console.log(getCurrentDateTime() + " ---- Connection to database successfully terminated."));
resolve();
});
}
async uploadData(data) {
return new Promise(async (resolve) => {
let promiseArray = [];
for (const entry of data) {
promiseArray.push(new Promise(async (resolve) => {
await this.pool.connect(async (error, client, release) => {
if (error) {
console.error(getCurrentDateTime() + " ----- Error getting client. Error :: ", error.stack);
}
await client.query("query", (error, result, release) => {
release();
if (error) {
console.error(getCurrentDateTime() + " ----- Error executing query :: ", error.stack);
}
resolve();
});
});
}));
}
await Promise.all(promiseArray);
resolve();
});
}
}
export { PoolConnection }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.