@@ -29,9 +29,8 @@ use tracing::error;
29
29
use super :: file_backed_index:: FileBackedIndex ;
30
30
use super :: store_operations:: { load_index, METASTORE_FILE_NAME } ;
31
31
32
- /// Lazy [`FileBackedIndex`]. It loads a `FileBackedIndex`
33
- /// on demand and optionally spawns a task to poll
34
- /// regularly the storage and update the index.
32
+ /// Lazy [`FileBackedIndex`]. It loads a `FileBackedIndex` on demand. When the index is first
33
+ /// loaded, it optionally spawns a task to regularly poll the storage and update the index.
35
34
pub ( crate ) struct LazyFileBackedIndex {
36
35
index_id : IndexId ,
37
36
storage : Arc < dyn Storage > ,
@@ -48,8 +47,8 @@ impl LazyFileBackedIndex {
48
47
file_backed_index : Option < FileBackedIndex > ,
49
48
) -> Self {
50
49
let index_mutex_opt = file_backed_index. map ( |index| Arc :: new ( Mutex :: new ( index) ) ) ;
51
- // If an index is given and a polling interval is given ,
52
- // spawn immediately the polling task.
50
+ // If the polling interval is configured and the index is already loaded ,
51
+ // spawn immediately the polling task
53
52
if let Some ( index_mutex) = & index_mutex_opt {
54
53
if let Some ( polling_interval) = polling_interval_opt {
55
54
spawn_index_metadata_polling_task (
@@ -68,15 +67,24 @@ impl LazyFileBackedIndex {
68
67
}
69
68
}
70
69
71
- /// Get `FileBackedIndex`.
70
+ /// Get a syncronized `FileBackedIndex`. If the index wasn't provided on creation, we load it
71
+ /// lazily on the first call of this method.
72
72
pub async fn get ( & self ) -> MetastoreResult < Arc < Mutex < FileBackedIndex > > > {
73
73
self . lazy_index
74
- . get_or_try_init ( || {
75
- load_file_backed_index (
76
- self . storage . clone ( ) ,
77
- self . index_id . clone ( ) ,
78
- self . polling_interval_opt ,
79
- )
74
+ . get_or_try_init ( || async move {
75
+ let index = load_index ( & * self . storage , & self . index_id ) . await ?;
76
+ let index_mutex = Arc :: new ( Mutex :: new ( index) ) ;
77
+ // When the index is loaded lazily, the polling task is not started in the
78
+ // constructor so we do it here when the index is actually loaded.
79
+ if let Some ( polling_interval) = self . polling_interval_opt {
80
+ spawn_index_metadata_polling_task (
81
+ self . storage . clone ( ) ,
82
+ self . index_id . clone ( ) ,
83
+ Arc :: downgrade ( & index_mutex) ,
84
+ polling_interval,
85
+ ) ;
86
+ }
87
+ Ok ( index_mutex)
80
88
} )
81
89
. await
82
90
. cloned ( )
@@ -122,6 +130,7 @@ fn spawn_index_metadata_polling_task(
122
130
) {
123
131
tokio:: task:: spawn ( async move {
124
132
let mut interval = tokio:: time:: interval ( polling_interval) ;
133
+ interval. set_missed_tick_behavior ( tokio:: time:: MissedTickBehavior :: Delay ) ;
125
134
interval. tick ( ) . await ; //< this is to prevent fetch right after the first population of the data.
126
135
127
136
while let Some ( metadata_mutex) = metastore_weak. upgrade ( ) {
@@ -130,21 +139,3 @@ fn spawn_index_metadata_polling_task(
130
139
}
131
140
} ) ;
132
141
}
133
-
134
- async fn load_file_backed_index (
135
- storage : Arc < dyn Storage > ,
136
- index_id : IndexId ,
137
- polling_interval_opt : Option < Duration > ,
138
- ) -> MetastoreResult < Arc < Mutex < FileBackedIndex > > > {
139
- let index = load_index ( & * storage, & index_id) . await ?;
140
- let index_mutex = Arc :: new ( Mutex :: new ( index) ) ;
141
- if let Some ( polling_interval) = polling_interval_opt {
142
- spawn_index_metadata_polling_task (
143
- storage. clone ( ) ,
144
- index_id. clone ( ) ,
145
- Arc :: downgrade ( & index_mutex) ,
146
- polling_interval,
147
- ) ;
148
- }
149
- Ok ( index_mutex)
150
- }
0 commit comments