2020use std:: sync:: { Arc , Weak } ;
2121use std:: time:: Duration ;
2222
23- use quickwit_proto:: metastore:: MetastoreResult ;
23+ use quickwit_proto:: metastore:: { EntityKind , MetastoreError , MetastoreResult } ;
2424use quickwit_proto:: types:: IndexId ;
2525use quickwit_storage:: Storage ;
2626use tokio:: sync:: { Mutex , OnceCell } ;
2727use tracing:: error;
2828
2929use super :: file_backed_index:: FileBackedIndex ;
30- use super :: store_operations:: load_index;
30+ use super :: store_operations:: { load_index, METASTORE_FILE_NAME } ;
3131
3232/// Lazy [`FileBackedIndex`]. It loads a `FileBackedIndex`
3333/// on demand and optionally spawns a task to poll
@@ -86,19 +86,30 @@ impl LazyFileBackedIndex {
8686async fn poll_index_metadata_once (
8787 storage : & dyn Storage ,
8888 index_id : & str ,
89- metadata_mutex : & Mutex < FileBackedIndex > ,
89+ index_mutex : & Mutex < FileBackedIndex > ,
9090) {
91- let mut metadata_lock = metadata_mutex . lock ( ) . await ;
92- if metadata_lock . flip_recently_modified_down ( ) {
91+ let mut locked_index = index_mutex . lock ( ) . await ;
92+ if locked_index . flip_recently_modified_down ( ) {
9393 return ;
9494 }
95- let index_fetch_res = load_index ( storage, index_id) . await ;
96- match index_fetch_res {
95+ let load_index_result = load_index ( storage, index_id) . await ;
96+
97+ match load_index_result {
9798 Ok ( index) => {
98- * metadata_lock = index;
99+ * locked_index = index;
100+ }
101+ Err ( MetastoreError :: NotFound ( EntityKind :: Index { .. } ) ) => {
102+ // The index has been deleted by the file-backed metastore holding a reference to this
103+ // index. When it removes an index, it does so without holding the lock on the target
104+ // index. As a result, the associated polling task may run for one
105+ // more iteration before exiting and `load_index` returns a `NotFound` error.
99106 }
100- Err ( fetch_error) => {
101- error ! ( error=?fetch_error, "fetch-metadata-error" ) ;
107+ Err ( metastore_error) => {
108+ error ! (
109+ error=%metastore_error,
110+ "failed to load index metadata from metastore file located at `{}/{index_id}/{METASTORE_FILE_NAME}`" ,
111+ storage. uri( )
112+ ) ;
102113 }
103114 }
104115}
@@ -112,6 +123,7 @@ fn spawn_index_metadata_polling_task(
112123 tokio:: task:: spawn ( async move {
113124 let mut interval = tokio:: time:: interval ( polling_interval) ;
114125 interval. tick ( ) . await ; //< this is to prevent fetch right after the first population of the data.
126+
115127 while let Some ( metadata_mutex) = metastore_weak. upgrade ( ) {
116128 interval. tick ( ) . await ;
117129 poll_index_metadata_once ( & * storage, & index_id, & metadata_mutex) . await ;
0 commit comments