Skip to content

Commit 7bd31a8

Browse files
authored
Merge pull request #142 from huggingface/feature/move-documents-count-to-analytics
Feature: move documents count to analytics node (if exists)
2 parents 22faf14 + 39d90c1 commit 7bd31a8

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ MONGOKU_COUNT_TIMEOUT=5000
145145
# Timeout for find queries in ms (Default = undefined, no timeout)
146146
MONGOKU_QUERY_TIMEOUT=30000
147147

148+
# Read preference for queries (primary, primaryPreferred, secondary, secondaryPreferred, nearest)
149+
MONGOKU_READ_PREFERENCE=secondaryPreferred
150+
151+
# Read preference tags as JSON array (used with MONGOKU_READ_PREFERENCE)
152+
# Example: route to analytics nodes with fallback to any node
153+
MONGOKU_READ_PREFERENCE_TAGS='[{"nodeType":"ANALYTICS"},{}]'
154+
148155
# Read-only mode (prevent write queries to mongodb)
149156
MONGOKU_READ_ONLY_MODE=true
150157

src/api/servers.remote.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,10 +985,7 @@ export const countDocumentsByTimeRange = query(
985985
try {
986986
const count = await coll.countDocuments(
987987
{ _id: { $gte: objectIdThreshold } },
988-
{
989-
maxTimeMS: mongo.getCountTimeout(),
990-
readPreference: ReadPreference.secondaryPreferred,
991-
},
988+
{ maxTimeMS: mongo.getCountTimeout() },
992989
);
993990
return { label, days, count, error: null };
994991
} catch (err) {

src/lib/server/mongo.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { logger } from "$lib/server/logger";
22
import type { CollectionJSON, CollectionMappings, Mappings } from "$lib/types";
33
import { resolveSrv } from "dns/promises";
4-
import { MongoClient, type Collection } from "mongodb";
4+
import { MongoClient, ReadPreference, type Collection } from "mongodb";
55
import { URL } from "url";
66
import { HostsManager } from "./HostsManager";
77

@@ -129,8 +129,8 @@ class MongoClientWithMappings extends MongoClient {
129129
_id: string;
130130
name: string;
131131

132-
constructor(url: string, _id: string, name: string) {
133-
super(url);
132+
constructor(url: string, _id: string, name: string, readPreference?: ReadPreference) {
133+
super(url, readPreference ? { readPreference } : {});
134134
this.url = url;
135135
this._id = _id;
136136
this.name = name;
@@ -164,6 +164,7 @@ class MongoConnections {
164164
? parseInt(process.env.MONGOKU_QUERY_TIMEOUT, 10)
165165
: undefined;
166166
private excludedDatabases: Set<string>;
167+
private readPreference: ReadPreference | undefined;
167168

168169
constructor() {
169170
this.hostsManager = new HostsManager();
@@ -175,6 +176,30 @@ class MongoConnections {
175176
.map((db) => db.trim())
176177
.filter((db) => db.length > 0),
177178
);
179+
180+
// Parse read preference from env vars
181+
// MONGOKU_READ_PREFERENCE: primary, primaryPreferred, secondary, secondaryPreferred, nearest
182+
// MONGOKU_READ_PREFERENCE_TAGS: JSON array of tag sets, e.g. [{"nodeType":"ANALYTICS"},{}]
183+
const readPrefMode = process.env.MONGOKU_READ_PREFERENCE as
184+
| "primary"
185+
| "primaryPreferred"
186+
| "secondary"
187+
| "secondaryPreferred"
188+
| "nearest"
189+
| undefined;
190+
191+
if (readPrefMode) {
192+
let tags: Array<Record<string, string>> | undefined;
193+
if (process.env.MONGOKU_READ_PREFERENCE_TAGS) {
194+
try {
195+
tags = JSON.parse(process.env.MONGOKU_READ_PREFERENCE_TAGS);
196+
} catch (err) {
197+
logger.error("Failed to parse MONGOKU_READ_PREFERENCE_TAGS:", err);
198+
}
199+
}
200+
this.readPreference = tags ? new ReadPreference(readPrefMode, tags) : new ReadPreference(readPrefMode);
201+
logger.log(`Read preference configured: ${readPrefMode}${tags ? ` with tags ${JSON.stringify(tags)}` : ""}`);
202+
}
178203
}
179204

180205
async initialize() {
@@ -189,7 +214,7 @@ class MongoConnections {
189214
const hostname = url.host || host.path;
190215

191216
if (!this.clients.has(hostname)) {
192-
const client = new MongoClientWithMappings(urlStr, host._id, hostname);
217+
const client = new MongoClientWithMappings(urlStr, host._id, hostname, this.readPreference);
193218
this.clients.set(host._id, client);
194219
this.clientIds.set(hostname, host._id);
195220
}
@@ -244,7 +269,7 @@ class MongoConnections {
244269
const hostname = url.host || hostPath;
245270

246271
if (!this.clients.has(hostname)) {
247-
const client = new MongoClientWithMappings(urlStr, id, hostname);
272+
const client = new MongoClientWithMappings(urlStr, id, hostname, this.readPreference);
248273
this.clients.set(id, client);
249274
this.clientIds.set(hostname, id);
250275
}
@@ -275,7 +300,7 @@ class MongoConnections {
275300
oldClient.close().catch((err) => logger.error(`Error closing old client ${id}:`, err));
276301

277302
// Create a new client
278-
const newClient = new MongoClientWithMappings(oldClient.url, id, oldClient.name);
303+
const newClient = new MongoClientWithMappings(oldClient.url, id, oldClient.name, this.readPreference);
279304
this.clients.set(id, newClient);
280305

281306
// Test the connection

0 commit comments

Comments
 (0)