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)
+ }
}
}