在调用 AWS lambda 处理程序回调时遇到 Neptune Gremlin 连接问题
Experience Neptune Gremlin connections problem on calling AWS lambda handlers` callback
我将 gremlin@3.3.5 用于我的 Node.js 8.10 应用程序和 AWS Lambdas。该过程对于单次调用一切正常。这是我的示例代码。
const gremlin = require('gremlin');
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const Graph = gremlin.structure.Graph;
exports.handler = (event, context, callback) => {
dc = new DriverRemoteConnection('wss://your-neptune-endpoint:8182/gremlin');
const graph = new Graph();
const g = graph.traversal().withRemote(dc);
try {
const result = await g.V().limit(1).count().next();
dc.close();
callback(null, { result: result });
} catch (exception) {
callback('Error');
throw error;
}
}
当我运行这个过程进行单次调用时,它似乎工作正常,但是当我尝试运行一个批处理操作时(大约 100,000 个请求/小时),我在 CloudWatch 日志指标中遇到我的连接未成功关闭的情况。我已经尝试了一些这样的实现,比如 callbackWaitForEventLoopEmpty,但是它占用了 lambda。当我删除回调(或类似地 return)时,此过程也适用于批处理操作。但我确实想要 return 来自此 lambda 的数据以及传递到我的步骤函数的信息,以根据该信息触发另一个 lambda。
g.V().limit(1).count().next()
是异步的。
试试这个:
exports.handler = async (event) => {
try {
dc = new DriverRemoteConnection('wss://your-neptune-endpoint:8182/gremlin');
const graph = new Graph();
const g = graph.traversal().withRemote(dc);
const result = await g.V().limit(1).count().next();
dc.close();
return result;
} catch (error) {
throw error;
}
}
由于您的 Lambda 运行时是 Node.js 8.10,因此您不需要使用 callback
。
经过一些研究,我发现问题出在 gremlin 包处理关闭连接事件的方式不利于无服务器架构。当触发 driver.close() 时。实例化驱动程序时,它会创建客户端实例,客户端实例在其内部创建连接实例,连接实例使用 ws 库创建 websocket 实例。现在 ws.close() 事件优雅地关闭了所有事件,它不会在调用我的回调之前等待事件被调用并且该事件保持打开状态并泄漏。因此在连接实例上显式调用 dc._client._connection.ws.terminate() 然后 dc.close() 立即关闭连接。
我将 gremlin@3.3.5 用于我的 Node.js 8.10 应用程序和 AWS Lambdas。该过程对于单次调用一切正常。这是我的示例代码。
const gremlin = require('gremlin');
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const Graph = gremlin.structure.Graph;
exports.handler = (event, context, callback) => {
dc = new DriverRemoteConnection('wss://your-neptune-endpoint:8182/gremlin');
const graph = new Graph();
const g = graph.traversal().withRemote(dc);
try {
const result = await g.V().limit(1).count().next();
dc.close();
callback(null, { result: result });
} catch (exception) {
callback('Error');
throw error;
}
}
当我运行这个过程进行单次调用时,它似乎工作正常,但是当我尝试运行一个批处理操作时(大约 100,000 个请求/小时),我在 CloudWatch 日志指标中遇到我的连接未成功关闭的情况。我已经尝试了一些这样的实现,比如 callbackWaitForEventLoopEmpty,但是它占用了 lambda。当我删除回调(或类似地 return)时,此过程也适用于批处理操作。但我确实想要 return 来自此 lambda 的数据以及传递到我的步骤函数的信息,以根据该信息触发另一个 lambda。
g.V().limit(1).count().next()
是异步的。
试试这个:
exports.handler = async (event) => {
try {
dc = new DriverRemoteConnection('wss://your-neptune-endpoint:8182/gremlin');
const graph = new Graph();
const g = graph.traversal().withRemote(dc);
const result = await g.V().limit(1).count().next();
dc.close();
return result;
} catch (error) {
throw error;
}
}
由于您的 Lambda 运行时是 Node.js 8.10,因此您不需要使用 callback
。
经过一些研究,我发现问题出在 gremlin 包处理关闭连接事件的方式不利于无服务器架构。当触发 driver.close() 时。实例化驱动程序时,它会创建客户端实例,客户端实例在其内部创建连接实例,连接实例使用 ws 库创建 websocket 实例。现在 ws.close() 事件优雅地关闭了所有事件,它不会在调用我的回调之前等待事件被调用并且该事件保持打开状态并泄漏。因此在连接实例上显式调用 dc._client._connection.ws.terminate() 然后 dc.close() 立即关闭连接。