diff --git a/src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php index 30b436cfff..1135420a6e 100644 --- a/src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php @@ -115,6 +115,10 @@ final class DiffusionLastModifiedQueryConduitAPIMethod $graph_cache = new PhabricatorRepositoryGraphCache(); $results = array(); + + // Spend no more than this many total seconds trying to satisfy queries + // via the graph cache. + $remaining_time = 10.0; foreach ($map as $path => $commit) { $path_id = idx($path_map, $path); if (!$path_id) { @@ -125,13 +129,21 @@ final class DiffusionLastModifiedQueryConduitAPIMethod continue; } + $t_start = microtime(true); $cache_result = $graph_cache->loadLastModifiedCommitID( $commit_id, - $path_id); + $path_id, + $remaining_time); + $t_end = microtime(true); if ($cache_result !== false) { $results[$path] = $cache_result; } + + $remaining_time -= ($t_end - $t_start); + if ($remaining_time <= 0) { + break; + } } if ($results) { diff --git a/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php b/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php index d52182fcc9..c4adc61ab0 100644 --- a/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php +++ b/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php @@ -102,6 +102,10 @@ final class PhabricatorRepositoryGraphCache extends Phobject { } // Otherwise, the rebuild gave us the data, so we can keep going. + + $did_fill = true; + } else { + $did_fill = false; } // Sanity check so we can survive and recover from bad data. @@ -147,12 +151,17 @@ final class PhabricatorRepositoryGraphCache extends Phobject { $commit_id = $parent_id; // Periodically check if we've spent too long looking for a result - // in the cache, and return so we can fall back to a VCS operation. This - // keeps us from having a degenerate worst case if, e.g., the cache - // is cold and we need to inspect a very large number of blocks + // in the cache, and return so we can fall back to a VCS operation. + // This keeps us from having a degenerate worst case if, e.g., the + // cache is cold and we need to inspect a very large number of blocks // to satisfy the query. - if (((++$iterations) % 64) === 0) { + ++$iterations; + + // If we performed a cache fill in this cycle, always check the time + // limit, since cache fills may take a significant amount of time. + + if ($did_fill || ($iterations % 64 === 0)) { $t_end = microtime(true); if (($t_end - $t_start) > $time) { return false;