@@ -220,33 +220,51 @@ impl IndexMapper {
220
220
221
221
drop ( lock) ;
222
222
223
- let current_size = index. map_size ( ) ?;
224
- let new_size = current_size * 2 ;
225
- let closing_event = index. prepare_for_closing ( ) ;
223
+ let resize_succeeded = ( move || {
224
+ let current_size = index. map_size ( ) ?;
225
+ let new_size = current_size * 2 ;
226
+ let closing_event = index. prepare_for_closing ( ) ;
226
227
227
- log:: debug!( "Waiting for index {name} to close" ) ;
228
+ log:: debug!( "Waiting for index {name} to close" ) ;
228
229
229
- if !closing_event. wait_timeout ( std:: time:: Duration :: from_secs ( 600 ) ) {
230
- // fail after 10 minutes waiting
231
- panic ! ( "Could not resize index {name} (unable to close it)" ) ;
232
- }
230
+ if !closing_event. wait_timeout ( std:: time:: Duration :: from_secs ( 600 ) ) {
231
+ // fail after 10 minutes waiting
232
+ panic ! ( "Could not resize index {name} (unable to close it)" ) ;
233
+ }
233
234
234
- log:: info!( "Resized index {name} from {current_size} to {new_size} bytes" ) ;
235
+ log:: info!( "Resized index {name} from {current_size} to {new_size} bytes" ) ;
236
+ let index_path = self . base_path . join ( uuid. to_string ( ) ) ;
237
+ let index = self . create_or_open_index ( & index_path, None , new_size) ?;
238
+ Ok ( index)
239
+ } ) ( ) ;
235
240
236
- let index_path = self . base_path . join ( uuid. to_string ( ) ) ;
237
- let index = self . create_or_open_index ( & index_path, None , new_size) ?;
238
-
239
- // Add back the resized index
241
+ // Put the map back to a consistent state.
242
+ // Even if there was an error we don't want to leave the map in an inconsistent state as it would cause
243
+ // deadlocks.
240
244
let mut lock = self . index_map . write ( ) . unwrap ( ) ;
241
- let Some ( BeingResized ( resize_operation) ) = lock. insert ( uuid, Available ( index) ) else {
242
- panic ! ( "Index state for index {name} was modified while it was being resized" )
245
+ let ( resize_operation, resize_succeeded) = match resize_succeeded {
246
+ Ok ( index) => {
247
+ // insert the resized index
248
+ let Some ( BeingResized ( resize_operation) ) = lock. insert ( uuid, Available ( index) ) else {
249
+ panic ! ( "Index state for index {name} was modified while it was being resized" )
250
+ } ;
251
+
252
+ ( resize_operation, Ok ( ( ) ) )
253
+ }
254
+ Err ( error) => {
255
+ // there was an error, not much we can do... delete the index from the in-memory map to prevent future errors
256
+ let Some ( BeingResized ( resize_operation) ) = lock. remove ( & uuid) else {
257
+ panic ! ( "Index state for index {name} was modified while it was being resized" )
258
+ } ;
259
+ ( resize_operation, Err ( error) )
260
+ }
243
261
} ;
244
262
245
263
// drop the lock before signaling completion so that other threads don't immediately await on the lock after waking up.
246
264
drop ( lock) ;
247
265
resize_operation. signal ( ) ;
248
266
249
- Ok ( ( ) )
267
+ resize_succeeded
250
268
}
251
269
252
270
/// Return an index, may open it if it wasn't already opened.
0 commit comments