I’ve not been able to find any guidance on a best practice for a request lifetime with respect to DgraphClientStub
, DgraphClient
within the context of a server process. Given a node server with a module that implements request handlers with something like express
or koa
what are the best practices for the lifetime of instances of these classes.
Here is what I’m currently doing which will run for the lifetime of the node server instance. This works great but I’m wondering if it is necessary to create the DgraphClientStub
on each request and further I have the same question for the DgraphClient
. I’m assuming the overhead for creating these instances on each request has some overhead which could be avoided in a high performance environment.
Lastly I have seen some community client apps that create both on startup and keep them live for the duration of the app - although not my case it made me question this same thing on the server side.
import { Context } from 'koa';
import Router from '@koa/router';
import { DgraphClientStub, DgraphClient } from 'dgraph-js';
import grpc from 'grpc';
// Dgraph GraphQL router for handling GraphQL operations
export const dgqlRouter = new Router();
const endpoints = (process.env.DGRAPH_ENDPOINTS || 'localhost:9080').split(',');
function createClientStubs() {
return endpoints.map((e) => new DgraphClientStub(e, grpc.credentials.createInsecure()));
}
function releaseStubs(stubs: DgraphClientStub[]) {
for (const stub of stubs) {
stub.close();
}
}
/**
* Passthrough GraphQL route for running
* pure Dgraph GraphQL against the db
*/
dgqlRouter.post('/dgql', async (ctx: Context) => {
// TODO: Add queryId functionality
const { query, vars } = ctx.request.body;
if (!query) {
ctx.status = 400;
return;
}
// NOTE: I'm not sure if this should be created for each request or once
// in this module - how would one clean it up on shutdown?
// See: https://github.com/dgraph-io/dgraph-js#cleanup-resources
const stubs = createClientStubs();
try {
const client = new DgraphClient(...stubs);
if (vars) {
const res = await client.newTxn().queryWithVars(query, vars);
ctx.body = { error: false, result: res.getJson() };
} else {
const res = await client.newTxn().query(query);
ctx.body = { error: false, result: res.getJson() };
}
} catch (e) {
ctx.body = { error: true, message: e.toString() };
} finally {
releaseStubs(stubs);
}
});