11import { logger } from "$lib/server/logger" ;
22import type { CollectionJSON , CollectionMappings , Mappings } from "$lib/types" ;
33import { resolveSrv } from "dns/promises" ;
4- import { MongoClient , type Collection } from "mongodb" ;
4+ import { MongoClient , ReadPreference , type Collection } from "mongodb" ;
55import { URL } from "url" ;
66import { 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