0
\$\begingroup\$

I was facing an issue with changing models on the fly — since we don’t just need isolation based on string or ID, but also data-level differences for each HIMS instance. To handle this, I created a simple library. Could you help me verify if this approach will work, and point out any potential issues I might face with aggregation? I’m already aware that aggregation can't be performed between two different databases.

// utils/TenantConnectionManager.js
import mongoose from "mongoose";
class TenantConnectionManager {
 constructor() {
 this.connections = {}; // { apiKey: { conn, timer } }
 this.TIMEOUT = 60 * 60 * 1000; // 1 hour
 }
 /**
 * Get or create a tenant connection
 */
 async getConnection(apiKey, dbURI) {
 if (this.connections[apiKey]) {
 // Reset timeout
 clearTimeout(this.connections[apiKey].timer);
 this.connections[apiKey].timer = setTimeout(() => {
 this.disconnect(apiKey);
 }, this.TIMEOUT);
 return this.connections[apiKey].conn;
 }
 // Create fresh connection
 const conn = await mongoose.createConnection(dbURI, {
 useNewUrlParser: true,
 useUnifiedTopology: true,
 });
 const timer = setTimeout(() => {
 this.disconnect(apiKey);
 }, this.TIMEOUT);
 this.connections[apiKey] = { conn, timer };
 console.log(`✅ Connected to tenant DB for API key: ${apiKey}`);
 return conn;
 }
 /**
 * Disconnect tenant DB
 */
 async disconnect(apiKey) {
 if (this.connections[apiKey]) {
 await this.connections[apiKey].conn.close();
 clearTimeout(this.connections[apiKey].timer);
 delete this.connections[apiKey];
 console.log(`❌ Disconnected tenant DB for API key: ${apiKey}`);
 }
 }
 /**
 * Register a model on a tenant connection
 */
 async setModel(apiKey, dbURI, modelName, schema) {
 const conn = await this.getConnection(apiKey, dbURI);
 if (!conn.models[modelName]) {
 try {
 conn.model(modelName, schema);
 } catch (err) {
 if (err.name !== "OverwriteModelError") throw err;
 }
 }
 return conn.model(modelName);
 }
 /**
 * Get a registered model
 */
 async getModel(apiKey, dbURI, modelName) {
 const conn = await this.getConnection(apiKey, dbURI);
 if (!conn.models[modelName]) {
 throw new Error(
 `Model "${modelName}" not registered for tenant ${apiKey}`
 );
 }
 return conn.model(modelName);
 }
}
export default new TenantConnectionManager();
toolic
15.8k6 gold badges29 silver badges217 bronze badges
asked 15 hours ago
\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.