@@ -113,6 +113,7 @@ function openRocksDatabase(path: string, options: RocksDatabaseOptions & { dupSo
113113 db = RocksDatabase . open ( new RocksIndexStore ( path , options ) ) as RocksDatabaseEx ;
114114 } else {
115115 db = RocksDatabase . open ( path , options ) as RocksDatabaseEx ;
116+ db . encoder . name = options . name ;
116117 }
117118 db . env = { } ;
118119 return db ;
@@ -847,7 +848,7 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
847848 if ( attribute . expiresAt ) attribute . indexed = true ;
848849 }
849850 let hasChanges ;
850- let txnCommit ;
851+ let releaseExclusiveLock : ( ) => void ;
851852 if ( Table ) {
852853 primaryKey = Table . primaryKey ;
853854 if ( Table . primaryStore . rootStore . status === 'closed' ) {
@@ -891,10 +892,10 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
891892 attributesDbi = rootStore . dbisDb = rootStore . openDB ( INTERNAL_DBIS_NAME , internalDbiInit ) ;
892893 }
893894
894- startTxn ( ) ; // get an exclusive lock on the database so we can verify that we are the only thread creating the table (and assigning the table id)
895+ exclusiveLock ( ) ; // get an exclusive lock on the database so we can verify that we are the only thread creating the table (and assigning the table id)
895896 if ( attributesDbi . getSync ( dbiName ) ) {
896897 // table was created while we were setting up
897- if ( txnCommit ) txnCommit ( ) ;
898+ if ( releaseExclusiveLock ) releaseExclusiveLock ( ) ;
898899 resetDatabases ( ) ;
899900 return table ( tableDefinition ) ;
900901 }
@@ -969,7 +970,7 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
969970 const attribute = attributes . find ( ( attribute ) => attribute . name === attribute_name ) ;
970971 const removeIndex = ! attribute ?. indexed && value . indexed && ! value . isPrimaryKey ;
971972 if ( ! attribute || removeIndex ) {
972- startTxn ( ) ;
973+ exclusiveLock ( ) ;
973974 hasChanges = true ;
974975 if ( ! attribute ) attributesDbi . remove ( key ) ;
975976 if ( removeIndex ) {
@@ -1012,7 +1013,7 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
10121013 if ( replicate !== undefined ) updatedPrimaryAttribute . replicate = replicate ;
10131014 if ( attribute . type ) updatedPrimaryAttribute . type = attribute . type ;
10141015 hasChanges = true ; // send out notification of the change
1015- startTxn ( ) ;
1016+ exclusiveLock ( ) ;
10161017 attributesDbi . put ( dbiKey , updatedPrimaryAttribute ) ;
10171018 }
10181019
@@ -1038,7 +1039,7 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
10381039 attributeDescriptor . restartNumber < workerData ?. restartNumber
10391040 ) {
10401041 hasChanges = true ;
1041- startTxn ( ) ;
1042+ exclusiveLock ( ) ;
10421043 attributeDescriptor = attributesDbi . getSync ( dbiKey ) ;
10431044 if (
10441045 changed ||
@@ -1068,12 +1069,12 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
10681069 indices [ attribute . name ] = dbi ;
10691070 } else if ( changed ) {
10701071 hasChanges = true ;
1071- startTxn ( ) ;
1072+ exclusiveLock ( ) ;
10721073 attributesDbi . put ( dbiKey , attribute ) ;
10731074 }
10741075 }
10751076 } finally {
1076- if ( txnCommit ) txnCommit ( ) ;
1077+ if ( releaseExclusiveLock ) releaseExclusiveLock ( ) ;
10771078 }
10781079 if ( hasChanges ) {
10791080 Table . schemaVersion ++ ;
@@ -1102,15 +1103,24 @@ export function table<TableResourceType>(tableDefinition: TableDefinition): Tabl
11021103 logger . trace ( `${ tableName } table loaded` ) ;
11031104
11041105 return Table as TableResourceType ;
1105- function startTxn ( ) {
1106- if ( txnCommit ) return ;
1107- rootStore . transactionSync ( ( ) => {
1108- return {
1109- then ( callback ) {
1110- txnCommit = callback ;
1111- } ,
1106+ // Acquire an exclusive lock for attribute updates
1107+ function exclusiveLock ( ) {
1108+ if ( releaseExclusiveLock ) return ;
1109+ if ( rootStore instanceof RocksDatabase ) {
1110+ while ( ! rootStore . tryLock ( 'update-attributes' ) ) { } // use a spin lock, we really need an synchronous exclusive lock here
1111+ releaseExclusiveLock = ( ) => {
1112+ rootStore . unlock ( 'update-attributes' ) ;
11121113 } ;
1113- } ) ;
1114+ } else {
1115+ // we only need an exclusive transaction lock in lmdb
1116+ rootStore . transactionSync ( ( ) => {
1117+ return {
1118+ then ( callback ) {
1119+ releaseExclusiveLock = callback ;
1120+ } ,
1121+ } ;
1122+ } ) ;
1123+ }
11141124 }
11151125}
11161126const MAX_OUTSTANDING_INDEXING = 1000 ;
0 commit comments