1515namespace {
1616using namespace moxygen ;
1717
18+ constexpr uint64_t kFetchYieldInterval = 1000 ;
19+ constexpr uint64_t kFetchMaxMissIterations = 100'000 ;
20+
1821// Splits one contiguous cache miss region into multiple intervals
1922// Depending on whether we are fetching asc or desc
2023// For asc, no split. Desc cases may or may not need splitting
@@ -1298,6 +1301,7 @@ folly::coro::Task<Publisher::FetchResult> MoQCache::fetchImpl(
12981301 auto cachedNow = now ();
12991302 FetchRangeIterator fetchRangeIt (
13001303 standalone->start , standalone->end , fetch.groupOrder , track);
1304+ uint64_t missIterCount = 0 ;
13011305 while (!token.isCancellationRequested () &&
13021306 (*fetchRangeIt) != fetchRangeIt.end ()) {
13031307 auto current = *fetchRangeIt;
@@ -1318,10 +1322,25 @@ folly::coro::Task<Publisher::FetchResult> MoQCache::fetchImpl(
13181322 if (!fetchStart) {
13191323 fetchStart = current;
13201324 }
1325+ if (++missIterCount > kFetchMaxMissIterations ) {
1326+ XLOG (ERR ) << " fetchImpl exceeded max miss iterations ("
1327+ << kFetchMaxMissIterations << " ) at {" << current.group
1328+ << " ," << current.object << " }, aborting fetch" ;
1329+ consumer->reset (ResetStreamErrorCode::INTERNAL_ERROR );
1330+ co_return folly::makeUnexpected (FetchError{
1331+ fetch.requestID ,
1332+ FetchErrorCode::INTERNAL_ERROR ,
1333+ " fetch loop exceeded max miss iterations" });
1334+ }
1335+ if (missIterCount % kFetchYieldInterval == 0 ) {
1336+ co_await folly::coro::co_reschedule_on_current_executor;
1337+ cachedNow = now ();
1338+ }
13211339 fetchRangeIt.next ();
13221340 continue ;
13231341 }
13241342
1343+ missIterCount = 0 ;
13251344 // found the object, first fetch missing range, if any
13261345 XLOG (DBG1 ) << " object cache HIT for {" << current.group << " ,"
13271346 << current.object << " }" ;
0 commit comments