@@ -45,7 +45,9 @@ export async function checkAndImportDatabaseIntegrity(event: H3Event, collection
45
45
if ( checkDatabaseIntegrity [ String ( collection ) ] !== false ) {
46
46
checkDatabaseIntegrity [ String ( collection ) ] = false
47
47
integrityCheckPromise [ String ( collection ) ] = integrityCheckPromise [ String ( collection ) ] || _checkAndImportDatabaseIntegrity ( event , collection , checksums [ String ( collection ) ] , config )
48
- . then ( ( isValid ) => { checkDatabaseIntegrity [ String ( collection ) ] = ! isValid } )
48
+ . then ( ( isValid ) => {
49
+ checkDatabaseIntegrity [ String ( collection ) ] = ! isValid
50
+ } )
49
51
. catch ( ( error ) => {
50
52
console . error ( 'Database integrity check failed' , error )
51
53
checkDatabaseIntegrity [ String ( collection ) ] = true
@@ -61,13 +63,44 @@ export async function checkAndImportDatabaseIntegrity(event: H3Event, collection
61
63
async function _checkAndImportDatabaseIntegrity ( event : H3Event , collection : string , integrityVersion : string , config : RuntimeConfig [ 'content' ] ) {
62
64
const db = loadDatabaseAdapter ( config )
63
65
64
- const before = await db . first < { version : string } > ( `select * from ${ tables . info } where id = ?` , [ `checksum_${ collection } ` ] ) . catch ( ( ) => ( { version : '' } ) )
66
+ const before : { version : string , ready : boolean } | null = await db . first < { version : string , ready : boolean } > ( `select * from ${ tables . info } where id = ?` , [ `checksum_${ collection } ` ] ) . catch ( ( ) : null => null )
65
67
66
68
if ( before ?. version ) {
67
- if ( before ?. version === integrityVersion ) {
69
+ if ( before . ready === true && before . version === integrityVersion ) {
70
+ // table is already initialized and ready, use it
71
+ return true
72
+ }
73
+
74
+ if ( before . ready === false && before . version === integrityVersion ) {
75
+ // if another request has already started the initialization of
76
+ // this version of this collection, wait for it to finish
77
+ // then respond that the database is ready
78
+ // NOTE: only wait if the version is the same so if the previous init
79
+ // was interrupted or has failed, it will not block the new init
80
+ let iterationCount = 0
81
+ await new Promise ( ( resolve , reject ) => {
82
+ const interval = setInterval ( async ( ) => {
83
+ const { ready } = await db . first < { ready : boolean } > ( `select ready from ${ tables . info } where id = ?` , [ `checksum_${ collection } ` ] ) . catch ( ( ) => ( { ready : true } ) )
84
+
85
+ if ( ready ) {
86
+ clearInterval ( interval )
87
+ resolve ( 0 )
88
+ }
89
+
90
+ // after timeout is reached, give up and stop the query
91
+ // it has to be that initialization has failed
92
+ if ( iterationCount ++ > 300 ) {
93
+ clearInterval ( interval )
94
+ reject ( new Error ( 'Waiting for another database initialization timed out' ) )
95
+ }
96
+ } , 1000 )
97
+ } ) . catch ( ( e ) => {
98
+ throw e
99
+ } )
68
100
return true
69
101
}
70
- // Delete old version
102
+
103
+ // Delete old version -- checksum exists but does not match with bundled checksum
71
104
await db . exec ( `DELETE FROM ${ tables . info } WHERE id = ?` , [ `checksum_${ collection } ` ] )
72
105
}
73
106
0 commit comments