@@ -139,6 +139,13 @@ function resolveStorageRootMtimeMs(rootDir: string): number {
139139 }
140140}
141141
142+ type PopulatedMatrixStorageRoot = {
143+ tokenHash : string ;
144+ rootDir : string ;
145+ score : number ;
146+ mtimeMs : number ;
147+ } ;
148+
142149export function normalizeMatrixStorageMetadata ( value : unknown ) : MatrixStorageMetadata | null {
143150 if ( ! isRecord ( value ) ) {
144151 return null ;
@@ -251,11 +258,12 @@ function resolvePreferredMatrixStorageRoot(params: {
251258} {
252259 const parentDir = path . dirname ( params . canonicalRootDir ) ;
253260 const bestCurrentScore = scoreStorageRoot ( params . canonicalRootDir ) ;
261+ const bestCurrentMtimeMs = resolveStorageRootMtimeMs ( params . canonicalRootDir ) ;
254262 let best = {
255263 rootDir : params . canonicalRootDir ,
256264 tokenHash : params . canonicalTokenHash ,
257265 score : bestCurrentScore ,
258- mtimeMs : resolveStorageRootMtimeMs ( params . canonicalRootDir ) ,
266+ mtimeMs : bestCurrentMtimeMs ,
259267 } ;
260268
261269 // Without a confirmed device identity, reusing a populated sibling root after
@@ -267,18 +275,6 @@ function resolvePreferredMatrixStorageRoot(params: {
267275 } ;
268276 }
269277
270- const canonicalMetadata = readStoredRootMetadata ( params . canonicalRootDir ) ;
271- if (
272- canonicalMetadata . accessTokenHash === params . canonicalTokenHash &&
273- canonicalMetadata . deviceId ?. trim ( ) === params . deviceId . trim ( ) &&
274- canonicalMetadata . currentTokenStateClaimed === true
275- ) {
276- return {
277- rootDir : best . rootDir ,
278- tokenHash : best . tokenHash ,
279- } ;
280- }
281-
282278 let siblingEntries : fs . Dirent [ ] ;
283279 try {
284280 siblingEntries = fs . readdirSync ( parentDir , { withFileTypes : true } ) ;
@@ -289,7 +285,9 @@ function resolvePreferredMatrixStorageRoot(params: {
289285 } ;
290286 }
291287
292- for ( const entry of siblingEntries ) {
288+ const compatiblePopulatedSiblings : PopulatedMatrixStorageRoot [ ] = [ ] ;
289+ const populatedTokenHashes = bestCurrentScore > 0 ? [ params . canonicalTokenHash ] : [ ] ;
290+ for ( const entry of siblingEntries . toSorted ( ( a , b ) => a . name . localeCompare ( b . name ) ) ) {
293291 if ( ! entry . isDirectory ( ) ) {
294292 continue ;
295293 }
@@ -315,22 +313,52 @@ function resolvePreferredMatrixStorageRoot(params: {
315313 if ( candidateScore <= 0 ) {
316314 continue ;
317315 }
318- const candidateMtimeMs = resolveStorageRootMtimeMs ( candidateRootDir ) ;
319- if (
320- candidateScore > best . score ||
321- ( best . rootDir !== params . canonicalRootDir &&
322- candidateScore === best . score &&
323- candidateMtimeMs > best . mtimeMs )
324- ) {
325- best = {
326- rootDir : candidateRootDir ,
327- tokenHash : entry . name ,
328- score : candidateScore ,
329- mtimeMs : candidateMtimeMs ,
330- } ;
316+ populatedTokenHashes . push ( entry . name ) ;
317+ compatiblePopulatedSiblings . push ( {
318+ rootDir : candidateRootDir ,
319+ tokenHash : entry . name ,
320+ score : candidateScore ,
321+ mtimeMs : resolveStorageRootMtimeMs ( candidateRootDir ) ,
322+ } ) ;
323+ }
324+
325+ const canonicalMetadata = readStoredRootMetadata ( params . canonicalRootDir ) ;
326+ const shouldKeepCanonicalCurrentRoot =
327+ canonicalMetadata . accessTokenHash === params . canonicalTokenHash &&
328+ canonicalMetadata . deviceId ?. trim ( ) === params . deviceId . trim ( ) &&
329+ canonicalMetadata . currentTokenStateClaimed === true ;
330+
331+ if ( ! shouldKeepCanonicalCurrentRoot ) {
332+ for ( const candidate of compatiblePopulatedSiblings ) {
333+ if (
334+ candidate . score > best . score ||
335+ ( best . rootDir !== params . canonicalRootDir &&
336+ candidate . score === best . score &&
337+ candidate . mtimeMs > best . mtimeMs )
338+ ) {
339+ best = {
340+ rootDir : candidate . rootDir ,
341+ tokenHash : candidate . tokenHash ,
342+ score : candidate . score ,
343+ mtimeMs : candidate . mtimeMs ,
344+ } ;
345+ }
331346 }
332347 }
333348
349+ if ( populatedTokenHashes . length > 1 ) {
350+ getMatrixRuntime ( )
351+ . logging . getChildLogger ( { module : "matrix-storage" } )
352+ . warn ( "matrix: multiple populated token-hash storage roots detected" , {
353+ parentDir,
354+ canonicalTokenHash : params . canonicalTokenHash ,
355+ selectedTokenHash : best . tokenHash ,
356+ populatedTokenHashes,
357+ populatedSiblingTokenHashes : compatiblePopulatedSiblings . map ( ( root ) => root . tokenHash ) ,
358+ populatedRootCount : populatedTokenHashes . length ,
359+ } ) ;
360+ }
361+
334362 return {
335363 rootDir : best . rootDir ,
336364 tokenHash : best . tokenHash ,
0 commit comments