@@ -181,9 +181,34 @@ void FileCacheBlockDownloader::download_file_cache_block(
181181 << " , rowset_id=" << meta.rowset_id () << " , segment_id=" << meta.segment_id ()
182182 << " , offset=" << meta.offset () << " , size=" << meta.size ()
183183 << " , type=" << meta.cache_type ();
184+
185+ // Helper to decrease inflight count on early return.
186+ // NOTE: This lambda captures 'this' pointer. It's safe because:
187+ // 1. download_segment_file() calls download_done synchronously
188+ // 2. ~FileCacheBlockDownloader() waits for all workers to finish via _workers->shutdown()
189+ // If this assumption changes (e.g., async callback), consider using shared_from_this pattern.
190+ auto decrease_inflight_count = [this , tablet_id = meta.tablet_id ()]() {
191+ std::lock_guard lock (_inflight_mtx);
192+ auto it = _inflight_tablets.find (tablet_id);
193+ if (it == _inflight_tablets.end ()) {
194+ LOG (WARNING) << " inflight ref cnt not exist, tablet id " << tablet_id;
195+ } else {
196+ it->second --;
197+ VLOG_DEBUG << " download_file_cache_block: inflight_tablets[" << tablet_id
198+ << " ] = " << it->second ;
199+ if (it->second <= 0 ) {
200+ DCHECK_EQ (it->second , 0 ) << it->first ;
201+ _inflight_tablets.erase (it);
202+ VLOG_DEBUG << " download_file_cache_block: erase inflight_tablets[" << tablet_id
203+ << " ]" ;
204+ }
205+ }
206+ };
207+
184208 CloudTabletSPtr tablet;
185209 if (auto res = _engine.tablet_mgr ().get_tablet (meta.tablet_id (), false ); !res.has_value ()) {
186210 LOG (INFO) << " failed to find tablet " << meta.tablet_id () << " : " << res.error ();
211+ decrease_inflight_count ();
187212 return ;
188213 } else {
189214 tablet = std::move (res).value ();
@@ -202,12 +227,14 @@ void FileCacheBlockDownloader::download_file_cache_block(
202227 if (find_it == id_to_rowset_meta_map.end ()) {
203228 LOG (WARNING) << " download_file_cache_block: tablet_id=" << meta.tablet_id ()
204229 << " rowset_id not found, rowset_id=" << meta.rowset_id ();
230+ decrease_inflight_count ();
205231 return ;
206232 }
207233
208234 auto storage_resource = find_it->second ->remote_storage_resource ();
209235 if (!storage_resource) {
210236 LOG (WARNING) << storage_resource.error ();
237+ decrease_inflight_count ();
211238 return ;
212239 }
213240 // Use RowsetMeta::fs() instead of storage_resource->fs to support packed file.
@@ -218,26 +245,15 @@ void FileCacheBlockDownloader::download_file_cache_block(
218245 if (!file_system) {
219246 LOG (WARNING) << " download_file_cache_block: failed to get file system for tablet_id="
220247 << meta.tablet_id () << " , rowset_id=" << meta.rowset_id ();
248+ decrease_inflight_count ();
221249 return ;
222250 }
223251
224- auto download_done = [&, tablet_id = meta. tablet_id ()](Status st) {
225- std::lock_guard lock (_inflight_mtx);
226- auto it = _inflight_tablets. find ( tablet_id);
252+ // Capture decrease_inflight_count by value to ensure lifetime safety
253+ // even if download_done is called asynchronously in the future
254+ auto download_done = [decrease_inflight_count, tablet_id = meta. tablet_id ()](Status st) {
227255 TEST_SYNC_POINT_CALLBACK (" FileCacheBlockDownloader::download_file_cache_block" );
228- if (it == _inflight_tablets.end ()) {
229- LOG (WARNING) << " inflight ref cnt not exist, tablet id " << tablet_id;
230- } else {
231- it->second --;
232- VLOG_DEBUG << " download_file_cache_block: inflight_tablets[" << tablet_id
233- << " ] = " << it->second ;
234- if (it->second <= 0 ) {
235- DCHECK_EQ (it->second , 0 ) << it->first ;
236- _inflight_tablets.erase (it);
237- VLOG_DEBUG << " download_file_cache_block: erase inflight_tablets[" << tablet_id
238- << " ]" ;
239- }
240- }
256+ decrease_inflight_count ();
241257 LOG (INFO) << " download_file_cache_block: download_done, tablet_Id=" << tablet_id
242258 << " status=" << st.to_string ();
243259 };
0 commit comments