import {
ContextId,
ContextIdFactory,
ContextIdStrategy,
HostComponentInfo,
} from '@nestjs/core';
import { Request } from 'express';
const tenants = new Map<string, { contextId: ContextId; lastTime: Date }>();
// can i do this?
setInterval(() => {
const now = new Date();
for (const [tenantId, { lastTime }] of tenants.entries()) {
if (now.getTime() - lastTime.getTime() > 1000 * 60 * 60) {
console.log(`Tenant ${tenantId} is expired`);
tenants.delete(tenantId);
}
}
}, 1000 * 60);
export class AggregateByTenantContextIdStrategy implements ContextIdStrategy {
attach(contextId: ContextId, request: Request) {
/* Extract the tenant identifier from the
request object into the tenantId variable */
console.log('AggregateByTenantContextIdStrategy...');
const tenantId = request.headers['x-tenant-id']?.toString();
let tenantSubTreeId: ContextId;
if (tenants.has(tenantId)) {
const tenant = tenants.get(tenantId);
tenantSubTreeId = tenant.contextId;
tenant.lastTime = new Date();
} else {
tenantSubTreeId = ContextIdFactory.create();
tenants.set(tenantId, { contextId, lastTime: new Date() });
}
return {
resolve: (info: HostComponentInfo) =>
info.isTreeDurable ? tenantSubTreeId : contextId,
payload: { tenantId },
};
}
}
#In NestJS, can I delete contextIds in the tenant Map to save RAM for tenants that haven't been used
26 messages · Page 1 of 1 (latest)
you can delete those entries because tenants Map is working like an in-memory cache, right
but I'd do this per access instead of with setInterval
thank you very much
with nestjs i converted my app to SaaS very quickly, thanks nestjs very much
if you want to stay with setInterval, I'd suggest you to call .unref() in the return of setInterval()
I removed setinterval as you noted.
About unref I don't understand clearly so will take time to learn. Thank you very much
@deft elbow What will happen when an attacker sends fake tenantIds? Will the app create new instances and occupy memory?
I have a middleware that intercepts at the beginning and its task is to check for fake tenantIds.
I have tested it myself, and it seems like the middleware successfully blocked it, but I am not sure if I am correct.
What will happen when an attacker sends fake tenantIds?
that's all up to your implementation
tenants.has(tenantId) would be false, so I didn't get why you're worried as this is like a 'cache miss', which is a valid path
I'm not worried about the cache map, I'm worried about something else
I am not sure if NestJS will create multiple instances corresponding to the fake tenant IDs. For example,
a request for tenant 1 results in NewsServices for tenant1,
a request for tenant 2 results in NewsServices for tenant2, which is fine.
But if there are requests for fake tenant 1 to fake tenant 10000, will NestJS create an additional 1000 instances of NewsServices or some other instances?
there's no 'fake tenant'
unless you implement that yourself
in that code you shared is just: a tenant id that is in the map and a tenant id there is not
That's not the point I'm trying to make, my English is not good, let me clarify the issue I'm still wondering about.
in your case, it will create a new subtree for that 'fake tenant', due to how you've implemented that logic
if you want to avoid that, you'd have to have a list of all valid tenant IDs or something like that
yes, i mean like this
if i block not valid tenant Ids in middleware
Does nestjs create instances of new services?
or some thing new instance
Thank you for your patience
but I'd say that if you raise an exception on that attach, nest won't instantiate anything
That's what I expected, at least