Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php b/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php
index 3e5b70cc05..f5960e9504 100644
--- a/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php
+++ b/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php
@@ -1,155 +1,175 @@
<?php
/**
* @task info Getting Collector Information
* @task collect Collecting Garbage
*/
abstract class PhabricatorGarbageCollector extends Phobject {
/* -( Getting Collector Information )-------------------------------------- */
/**
* Get a human readable name for what this collector cleans up, like
* "User Activity Logs".
*
* @return string Human-readable collector name.
* @task info
*/
abstract public function getCollectorName();
/**
* Specify that the collector has an automatic retention policy and
* is not configurable.
*
* @return bool True if the collector has an automatic retention policy.
* @task info
*/
public function hasAutomaticPolicy() {
return false;
}
/**
* Get the default retention policy for this collector.
*
* Return the age (in seconds) when resources start getting collected, or
* `null` to retain resources indefinitely.
*
* @return int|null Lifetime, or `null` for indefinite retention.
* @task info
*/
public function getDefaultRetentionPolicy() {
throw new PhutilMethodNotImplementedException();
}
/**
* Get the effective retention policy.
*
* @return int|null Lifetime, or `null` for indefinite retention.
* @task info
*/
public function getRetentionPolicy() {
if ($this->hasAutomaticPolicy()) {
throw new Exception(
pht(
'Can not get retention policy of collector with automatic '.
'policy.'));
}
$config = PhabricatorEnv::getEnvConfig('phd.garbage-collection');
$const = $this->getCollectorConstant();
return idx($config, $const, $this->getDefaultRetentionPolicy());
}
/**
* Get a unique string constant identifying this collector.
*
* @return string Collector constant.
* @task info
*/
final public function getCollectorConstant() {
return $this->getPhobjectClassConstant('COLLECTORCONST', 64);
}
/* -( Collecting Garbage )------------------------------------------------- */
/**
* Run the collector.
*
* @return bool True if there is more garbage to collect.
* @task collect
*/
final public function runCollector() {
// Don't do anything if this collector is configured with an indefinite
// retention policy.
if (!$this->hasAutomaticPolicy()) {
$policy = $this->getRetentionPolicy();
if (!$policy) {
return false;
}
}
- return $this->collectGarbage();
+ // Hold a lock while performing collection to avoid racing other daemons
+ // running the same collectors.
+ $lock_name = 'gc:'.$this->getCollectorConstant();
+ $lock = PhabricatorGlobalLock::newLock($lock_name);
+
+ try {
+ $lock->lock(5);
+ } catch (PhutilLockException $ex) {
+ return false;
+ }
+
+ try {
+ $result = $this->collectGarbage();
+ } catch (Exception $ex) {
+ $lock->unlock();
+ throw $ex;
+ }
+
+ $lock->unlock();
+
+ return $result;
}
/**
* Collect garbage from whatever source this GC handles.
*
* @return bool True if there is more garbage to collect.
* @task collect
*/
abstract protected function collectGarbage();
/**
* Get the most recent epoch timestamp that is considered garbage.
*
* Records older than this should be collected.
*
* @return int Most recent garbage timestamp.
* @task collect
*/
final protected function getGarbageEpoch() {
if ($this->hasAutomaticPolicy()) {
throw new Exception(
pht(
'Can not get garbage epoch for a collector with an automatic '.
'collection policy.'));
}
$ttl = $this->getRetentionPolicy();
if (!$ttl) {
throw new Exception(
pht(
'Can not get garbage epoch for a collector with an indefinite '.
'retention policy.'));
}
return (PhabricatorTime::getNow() - $ttl);
}
/**
* Load all of the available garbage collectors.
*
* @return list<PhabricatorGarbageCollector> Garbage collectors.
* @task collect
*/
final public static function getAllCollectors() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getCollectorConstant')
->execute();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Oct 31, 4:04 AM (5 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
311982
Default Alt Text
(4 KB)

Event Timeline