Remove stale packed-refs.lock files When a packed-refs.lock is stale for a long period of time (configurable) then do not just display a warning and metric but also remove the lock file from the filesystem. Change-Id: Icfb24e964be5659362d4d1cde52f6042ca4a8b82
diff --git a/admin/stale-packed-refs-1.0.groovy b/admin/stale-packed-refs-1.0.groovy index 9065998..c3aecdc 100644 --- a/admin/stale-packed-refs-1.0.groovy +++ b/admin/stale-packed-refs-1.0.groovy
@@ -8,6 +8,7 @@ import com.google.gerrit.metrics.Description import com.google.gerrit.metrics.Field import com.google.gerrit.metrics.MetricMaker +import com.google.gerrit.server.config.ConfigUtil import com.google.gerrit.server.config.PluginConfig import com.google.gerrit.server.config.PluginConfigFactory import com.google.gerrit.server.git.GitRepositoryManager @@ -45,6 +46,7 @@ private ScheduledFuture<?> scheduledCheckerTask private String[] projectPrefixes + private long removeAfter def CHECK_INTERVAL_SEC_DEFAULT = 10 @@ -59,10 +61,12 @@ PluginConfig pluginConfig = configFactory.getFromGerritConfig(pluginName) def checkInterval = pluginConfig.getInt("checkIntervalSec", CHECK_INTERVAL_SEC_DEFAULT) projectPrefixes = pluginConfig.getStringList("projectPrefix") + def staleRemovalTime = pluginConfig.getString("removeAfter") + removeAfter = staleRemovalTime ? ConfigUtil.getTimeUnit(staleRemovalTime, Long.MAX_VALUE, TimeUnit.MILLISECONDS) : Long.MAX_VALUE scheduledCheckerTask = workQueue.getDefaultQueue().scheduleAtFixedRate({ checkProjects() }, checkInterval, checkInterval, TimeUnit.SECONDS) logger.atInfo().log("packed-refs.lock staleness checker started for %d projects (checkIntervalSec=%d, projectPrefix=%s)", - allProjectsToCheck().size(), checkInterval, Arrays.copyOf(projectPrefixes, projectPrefixes.length)) + allProjectsToCheck().size(), checkInterval, Arrays.copyOf(projectPrefixes, projectPrefixes.length)) } private def allProjectsToCheck() { @@ -86,7 +90,7 @@ allProjectsToCheck().each { String projectName -> repoMgr.openRepository(Project.nameKey(projectName)).with { Repository it -> try { - recordLockFileAgeMetric(it, projectName) + recordLockFileAgeMetricAndRemoveIfStale(it, projectName) } catch (Exception e) { logger.atSevere().withCause(e).log("Error whilst checking project %s", projectName) } @@ -97,7 +101,7 @@ } } - private void recordLockFileAgeMetric(Repository repo, String projectName) { + private void recordLockFileAgeMetricAndRemoveIfStale(Repository repo, String projectName) { def repoDir = repo.getDirectory() logger.atFine().log("Checking project %s ... ", projectName) File packedRefsLock = new File(repoDir, "packed-refs.lock") @@ -110,7 +114,14 @@ def packedRefsLockMillis = FileUtils.lastModified(packedRefsLock.getAbsolutePath()) def lockFileAge = System.currentTimeMillis() - packedRefsLockMillis refdbMetrics.projectsAndLockFileAge.put(sanitizeProjectName.sanitize(projectName), lockFileAge) - logger.atFine().log("[%s] calculated age for lock file (creationMillis=%d)", projectName, lockFileAge) + + if (lockFileAge > removeAfter) { + def deleteOk = packedRefsLock.delete() + logger.atWarning().log("[%s] %s stale lock file (creationMillis=%d, ageMillis=%d): ", + projectName, deleteOk ? "deleted" : "*FAILED* to delete", packedRefsLockMillis, lockFileAge) + } else { + logger.atFine().log("[%s] calculated age for lock file (creationMillis=%d, ageMillis=%d)", projectName, packedRefsLockMillis, lockFileAge) + } } }