Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php
12242 views
1
<?php
2
3
/**
4
* @task info Getting Collector Information
5
* @task collect Collecting Garbage
6
*/
7
abstract class PhabricatorGarbageCollector extends Phobject {
8
9
10
/* -( Getting Collector Information )-------------------------------------- */
11
12
13
/**
14
* Get a human readable name for what this collector cleans up, like
15
* "User Activity Logs".
16
*
17
* @return string Human-readable collector name.
18
* @task info
19
*/
20
abstract public function getCollectorName();
21
22
23
/**
24
* Specify that the collector has an automatic retention policy and
25
* is not configurable.
26
*
27
* @return bool True if the collector has an automatic retention policy.
28
* @task info
29
*/
30
public function hasAutomaticPolicy() {
31
return false;
32
}
33
34
35
/**
36
* Get the default retention policy for this collector.
37
*
38
* Return the age (in seconds) when resources start getting collected, or
39
* `null` to retain resources indefinitely.
40
*
41
* @return int|null Lifetime, or `null` for indefinite retention.
42
* @task info
43
*/
44
public function getDefaultRetentionPolicy() {
45
throw new PhutilMethodNotImplementedException();
46
}
47
48
49
/**
50
* Get the effective retention policy.
51
*
52
* @return int|null Lifetime, or `null` for indefinite retention.
53
* @task info
54
*/
55
public function getRetentionPolicy() {
56
if ($this->hasAutomaticPolicy()) {
57
throw new Exception(
58
pht(
59
'Can not get retention policy of collector with automatic '.
60
'policy.'));
61
}
62
63
$config = PhabricatorEnv::getEnvConfig('phd.garbage-collection');
64
$const = $this->getCollectorConstant();
65
66
return idx($config, $const, $this->getDefaultRetentionPolicy());
67
}
68
69
70
71
/**
72
* Get a unique string constant identifying this collector.
73
*
74
* @return string Collector constant.
75
* @task info
76
*/
77
final public function getCollectorConstant() {
78
return $this->getPhobjectClassConstant('COLLECTORCONST', 64);
79
}
80
81
82
/* -( Collecting Garbage )------------------------------------------------- */
83
84
85
/**
86
* Run the collector.
87
*
88
* @return bool True if there is more garbage to collect.
89
* @task collect
90
*/
91
final public function runCollector() {
92
// Don't do anything if this collector is configured with an indefinite
93
// retention policy.
94
if (!$this->hasAutomaticPolicy()) {
95
$policy = $this->getRetentionPolicy();
96
if (!$policy) {
97
return false;
98
}
99
}
100
101
// Hold a lock while performing collection to avoid racing other daemons
102
// running the same collectors.
103
$params = array(
104
'collector' => $this->getCollectorConstant(),
105
);
106
$lock = PhabricatorGlobalLock::newLock('gc', $params);
107
108
try {
109
$lock->lock(5);
110
} catch (PhutilLockException $ex) {
111
return false;
112
}
113
114
try {
115
$result = $this->collectGarbage();
116
} catch (Exception $ex) {
117
$lock->unlock();
118
throw $ex;
119
}
120
121
$lock->unlock();
122
123
return $result;
124
}
125
126
127
/**
128
* Collect garbage from whatever source this GC handles.
129
*
130
* @return bool True if there is more garbage to collect.
131
* @task collect
132
*/
133
abstract protected function collectGarbage();
134
135
136
/**
137
* Get the most recent epoch timestamp that is considered garbage.
138
*
139
* Records older than this should be collected.
140
*
141
* @return int Most recent garbage timestamp.
142
* @task collect
143
*/
144
final protected function getGarbageEpoch() {
145
if ($this->hasAutomaticPolicy()) {
146
throw new Exception(
147
pht(
148
'Can not get garbage epoch for a collector with an automatic '.
149
'collection policy.'));
150
}
151
152
$ttl = $this->getRetentionPolicy();
153
if (!$ttl) {
154
throw new Exception(
155
pht(
156
'Can not get garbage epoch for a collector with an indefinite '.
157
'retention policy.'));
158
}
159
160
return (PhabricatorTime::getNow() - $ttl);
161
}
162
163
164
/**
165
* Load all of the available garbage collectors.
166
*
167
* @return list<PhabricatorGarbageCollector> Garbage collectors.
168
* @task collect
169
*/
170
final public static function getAllCollectors() {
171
return id(new PhutilClassMapQuery())
172
->setAncestorClass(__CLASS__)
173
->setUniqueMethod('getCollectorConstant')
174
->execute();
175
}
176
177
}
178
179