Completed
Push — master ( e4f06e...144e86 )
by
unknown
33:22
created
lib/private/Memcache/Factory.php 2 patches
Indentation   +222 added lines, -222 removed lines patch added patch discarded remove patch
@@ -18,226 +18,226 @@
 block discarded – undo
18 18
 use Psr\Log\LoggerInterface;
19 19
 
20 20
 class Factory implements ICacheFactory {
21
-	public const NULL_CACHE = NullCache::class;
22
-
23
-	protected ?string $globalPrefix = null;
24
-	/**
25
-	 * @var class-string<ICache> $localCacheClass
26
-	 */
27
-	protected string $localCacheClass;
28
-
29
-	/**
30
-	 * @var class-string<ICache> $distributedCacheClass
31
-	 */
32
-	protected string $distributedCacheClass;
33
-
34
-	/**
35
-	 * @var class-string<IMemcache> $lockingCacheClass
36
-	 */
37
-	protected string $lockingCacheClass;
38
-
39
-	/**
40
-	 * @param ?class-string<ICache> $localCacheClass
41
-	 * @param ?class-string<ICache> $distributedCacheClass
42
-	 * @param ?class-string<IMemcache> $lockingCacheClass
43
-	 */
44
-	public function __construct(
45
-		protected LoggerInterface $logger,
46
-		protected IProfiler $profiler,
47
-		protected ServerVersion $serverVersion,
48
-		?string $localCacheClass = null,
49
-		?string $distributedCacheClass = null,
50
-		?string $lockingCacheClass = null,
51
-		protected string $logFile = '',
52
-	) {
53
-		if (!$localCacheClass) {
54
-			$localCacheClass = self::NULL_CACHE;
55
-		}
56
-		$localCacheClass = ltrim($localCacheClass, '\\');
57
-
58
-		if (!$distributedCacheClass) {
59
-			$distributedCacheClass = $localCacheClass;
60
-		}
61
-		$distributedCacheClass = ltrim($distributedCacheClass, '\\');
62
-
63
-		$missingCacheMessage = 'Memcache {class} not available for {use} cache';
64
-		$missingCacheHint = 'Is the matching PHP module installed and enabled?';
65
-		if (!class_exists($localCacheClass)
66
-			|| !is_a($localCacheClass, ICache::class, true)
67
-			|| !$localCacheClass::isAvailable()
68
-		) {
69
-			if (\OC::$CLI && !defined('PHPUNIT_RUN') && $localCacheClass === APCu::class) {
70
-				// CLI should not fail if APCu is not available but fallback to NullCache.
71
-				// This can be the case if APCu is used without apc.enable_cli=1.
72
-				// APCu however cannot be shared between PHP instances (CLI and web) anyway.
73
-				$localCacheClass = self::NULL_CACHE;
74
-			} else {
75
-				throw new \OCP\HintException(strtr($missingCacheMessage, [
76
-					'{class}' => $localCacheClass, '{use}' => 'local'
77
-				]), $missingCacheHint);
78
-			}
79
-		}
80
-
81
-		if (!class_exists($distributedCacheClass)
82
-			|| !is_a($distributedCacheClass, ICache::class, true)
83
-			|| !$distributedCacheClass::isAvailable()
84
-		) {
85
-			if (\OC::$CLI && !defined('PHPUNIT_RUN') && $distributedCacheClass === APCu::class) {
86
-				// CLI should not fail if APCu is not available but fallback to NullCache.
87
-				// This can be the case if APCu is used without apc.enable_cli=1.
88
-				// APCu however cannot be shared between Nextcloud (PHP) instances anyway.
89
-				$distributedCacheClass = self::NULL_CACHE;
90
-			} else {
91
-				throw new \OCP\HintException(strtr($missingCacheMessage, [
92
-					'{class}' => $distributedCacheClass, '{use}' => 'distributed'
93
-				]), $missingCacheHint);
94
-			}
95
-		}
96
-
97
-		if (!$lockingCacheClass
98
-			|| !class_exists($lockingCacheClass)
99
-			|| !is_a($lockingCacheClass, IMemcache::class, true)
100
-			|| !$lockingCacheClass::isAvailable()
101
-		) {
102
-			// don't fall back since the fallback might not be suitable for storing lock
103
-			$lockingCacheClass = self::NULL_CACHE;
104
-		}
105
-		/** @var class-string<IMemcache> */
106
-		$lockingCacheClass = ltrim($lockingCacheClass, '\\');
107
-
108
-		$this->localCacheClass = $localCacheClass;
109
-		$this->distributedCacheClass = $distributedCacheClass;
110
-		$this->lockingCacheClass = $lockingCacheClass;
111
-	}
112
-
113
-	protected function getGlobalPrefix(): string {
114
-		if ($this->globalPrefix === null) {
115
-			$config = \OCP\Server::get(SystemConfig::class);
116
-			$versions = [];
117
-			if ($config->getValue('installed', false)) {
118
-				$appConfig = \OCP\Server::get(IAppConfig::class);
119
-				// only get the enabled apps to clear the cache in case an app is enabled or disabled (e.g. clear routes)
120
-				$versions = $appConfig->getAppInstalledVersions(true);
121
-				ksort($versions);
122
-			}
123
-			$versions['core'] = implode('.', $this->serverVersion->getVersion());
124
-
125
-			// Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
126
-			$instanceid = $config->getValue('instanceid');
127
-			$installedApps = implode(',', array_keys($versions)) . implode(',', array_values($versions));
128
-			$this->globalPrefix = hash('xxh128', $instanceid . $installedApps);
129
-		}
130
-		return $this->globalPrefix;
131
-	}
132
-
133
-	/**
134
-	 * Override the global prefix for a specific closure.
135
-	 * This should only be used internally for bootstrapping purpose!
136
-	 *
137
-	 * @param \Closure $closure - The closure with the cache factory as the first parameter
138
-	 */
139
-	public function withServerVersionPrefix(\Closure $closure): void {
140
-		$backupPrefix = $this->globalPrefix;
141
-
142
-		// Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
143
-		$instanceid = \OCP\Server::get(SystemConfig::class)->getValue('instanceid');
144
-		$this->globalPrefix = hash('xxh128', $instanceid . implode('.', $this->serverVersion->getVersion()));
145
-		$closure($this);
146
-		$this->globalPrefix = $backupPrefix;
147
-	}
148
-
149
-	/**
150
-	 * create a cache instance for storing locks
151
-	 *
152
-	 * @param string $prefix
153
-	 * @return IMemcache
154
-	 */
155
-	public function createLocking(string $prefix = ''): IMemcache {
156
-		$cache = new $this->lockingCacheClass($this->getGlobalPrefix() . '/' . $prefix);
157
-		if ($this->lockingCacheClass === Redis::class) {
158
-			if ($this->profiler->isEnabled()) {
159
-				// We only support the profiler with Redis
160
-				$cache = new ProfilerWrapperCache($cache, 'Locking');
161
-				$this->profiler->add($cache);
162
-			}
163
-
164
-			if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
165
-				$cache = new LoggerWrapperCache($cache, $this->logFile);
166
-			}
167
-		}
168
-		return $cache;
169
-	}
170
-
171
-	/**
172
-	 * create a distributed cache instance
173
-	 *
174
-	 * @param string $prefix
175
-	 * @return ICache
176
-	 */
177
-	public function createDistributed(string $prefix = ''): ICache {
178
-		$cache = new $this->distributedCacheClass($this->getGlobalPrefix() . '/' . $prefix);
179
-		if ($this->distributedCacheClass === Redis::class) {
180
-			if ($this->profiler->isEnabled()) {
181
-				// We only support the profiler with Redis
182
-				$cache = new ProfilerWrapperCache($cache, 'Distributed');
183
-				$this->profiler->add($cache);
184
-			}
185
-
186
-			if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
187
-				$cache = new LoggerWrapperCache($cache, $this->logFile);
188
-			}
189
-		}
190
-		return $cache;
191
-	}
192
-
193
-	/**
194
-	 * create a local cache instance
195
-	 *
196
-	 * @param string $prefix
197
-	 * @return ICache
198
-	 */
199
-	public function createLocal(string $prefix = ''): ICache {
200
-		$cache = new $this->localCacheClass($this->getGlobalPrefix() . '/' . $prefix);
201
-		if ($this->localCacheClass === Redis::class) {
202
-			if ($this->profiler->isEnabled()) {
203
-				// We only support the profiler with Redis
204
-				$cache = new ProfilerWrapperCache($cache, 'Local');
205
-				$this->profiler->add($cache);
206
-			}
207
-
208
-			if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
209
-				$cache = new LoggerWrapperCache($cache, $this->logFile);
210
-			}
211
-		}
212
-		return $cache;
213
-	}
214
-
215
-	/**
216
-	 * check memcache availability
217
-	 *
218
-	 * @return bool
219
-	 */
220
-	public function isAvailable(): bool {
221
-		return $this->distributedCacheClass !== self::NULL_CACHE;
222
-	}
223
-
224
-	public function createInMemory(int $capacity = 512): ICache {
225
-		return new CappedMemoryCache($capacity);
226
-	}
227
-
228
-	/**
229
-	 * Check if a local memory cache backend is available
230
-	 *
231
-	 * @return bool
232
-	 */
233
-	public function isLocalCacheAvailable(): bool {
234
-		return $this->localCacheClass !== self::NULL_CACHE;
235
-	}
236
-
237
-	public function clearAll(): void {
238
-		$this->createLocal()->clear();
239
-		$this->createDistributed()->clear();
240
-		$this->createLocking()->clear();
241
-		$this->createInMemory()->clear();
242
-	}
21
+    public const NULL_CACHE = NullCache::class;
22
+
23
+    protected ?string $globalPrefix = null;
24
+    /**
25
+     * @var class-string<ICache> $localCacheClass
26
+     */
27
+    protected string $localCacheClass;
28
+
29
+    /**
30
+     * @var class-string<ICache> $distributedCacheClass
31
+     */
32
+    protected string $distributedCacheClass;
33
+
34
+    /**
35
+     * @var class-string<IMemcache> $lockingCacheClass
36
+     */
37
+    protected string $lockingCacheClass;
38
+
39
+    /**
40
+     * @param ?class-string<ICache> $localCacheClass
41
+     * @param ?class-string<ICache> $distributedCacheClass
42
+     * @param ?class-string<IMemcache> $lockingCacheClass
43
+     */
44
+    public function __construct(
45
+        protected LoggerInterface $logger,
46
+        protected IProfiler $profiler,
47
+        protected ServerVersion $serverVersion,
48
+        ?string $localCacheClass = null,
49
+        ?string $distributedCacheClass = null,
50
+        ?string $lockingCacheClass = null,
51
+        protected string $logFile = '',
52
+    ) {
53
+        if (!$localCacheClass) {
54
+            $localCacheClass = self::NULL_CACHE;
55
+        }
56
+        $localCacheClass = ltrim($localCacheClass, '\\');
57
+
58
+        if (!$distributedCacheClass) {
59
+            $distributedCacheClass = $localCacheClass;
60
+        }
61
+        $distributedCacheClass = ltrim($distributedCacheClass, '\\');
62
+
63
+        $missingCacheMessage = 'Memcache {class} not available for {use} cache';
64
+        $missingCacheHint = 'Is the matching PHP module installed and enabled?';
65
+        if (!class_exists($localCacheClass)
66
+            || !is_a($localCacheClass, ICache::class, true)
67
+            || !$localCacheClass::isAvailable()
68
+        ) {
69
+            if (\OC::$CLI && !defined('PHPUNIT_RUN') && $localCacheClass === APCu::class) {
70
+                // CLI should not fail if APCu is not available but fallback to NullCache.
71
+                // This can be the case if APCu is used without apc.enable_cli=1.
72
+                // APCu however cannot be shared between PHP instances (CLI and web) anyway.
73
+                $localCacheClass = self::NULL_CACHE;
74
+            } else {
75
+                throw new \OCP\HintException(strtr($missingCacheMessage, [
76
+                    '{class}' => $localCacheClass, '{use}' => 'local'
77
+                ]), $missingCacheHint);
78
+            }
79
+        }
80
+
81
+        if (!class_exists($distributedCacheClass)
82
+            || !is_a($distributedCacheClass, ICache::class, true)
83
+            || !$distributedCacheClass::isAvailable()
84
+        ) {
85
+            if (\OC::$CLI && !defined('PHPUNIT_RUN') && $distributedCacheClass === APCu::class) {
86
+                // CLI should not fail if APCu is not available but fallback to NullCache.
87
+                // This can be the case if APCu is used without apc.enable_cli=1.
88
+                // APCu however cannot be shared between Nextcloud (PHP) instances anyway.
89
+                $distributedCacheClass = self::NULL_CACHE;
90
+            } else {
91
+                throw new \OCP\HintException(strtr($missingCacheMessage, [
92
+                    '{class}' => $distributedCacheClass, '{use}' => 'distributed'
93
+                ]), $missingCacheHint);
94
+            }
95
+        }
96
+
97
+        if (!$lockingCacheClass
98
+            || !class_exists($lockingCacheClass)
99
+            || !is_a($lockingCacheClass, IMemcache::class, true)
100
+            || !$lockingCacheClass::isAvailable()
101
+        ) {
102
+            // don't fall back since the fallback might not be suitable for storing lock
103
+            $lockingCacheClass = self::NULL_CACHE;
104
+        }
105
+        /** @var class-string<IMemcache> */
106
+        $lockingCacheClass = ltrim($lockingCacheClass, '\\');
107
+
108
+        $this->localCacheClass = $localCacheClass;
109
+        $this->distributedCacheClass = $distributedCacheClass;
110
+        $this->lockingCacheClass = $lockingCacheClass;
111
+    }
112
+
113
+    protected function getGlobalPrefix(): string {
114
+        if ($this->globalPrefix === null) {
115
+            $config = \OCP\Server::get(SystemConfig::class);
116
+            $versions = [];
117
+            if ($config->getValue('installed', false)) {
118
+                $appConfig = \OCP\Server::get(IAppConfig::class);
119
+                // only get the enabled apps to clear the cache in case an app is enabled or disabled (e.g. clear routes)
120
+                $versions = $appConfig->getAppInstalledVersions(true);
121
+                ksort($versions);
122
+            }
123
+            $versions['core'] = implode('.', $this->serverVersion->getVersion());
124
+
125
+            // Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
126
+            $instanceid = $config->getValue('instanceid');
127
+            $installedApps = implode(',', array_keys($versions)) . implode(',', array_values($versions));
128
+            $this->globalPrefix = hash('xxh128', $instanceid . $installedApps);
129
+        }
130
+        return $this->globalPrefix;
131
+    }
132
+
133
+    /**
134
+     * Override the global prefix for a specific closure.
135
+     * This should only be used internally for bootstrapping purpose!
136
+     *
137
+     * @param \Closure $closure - The closure with the cache factory as the first parameter
138
+     */
139
+    public function withServerVersionPrefix(\Closure $closure): void {
140
+        $backupPrefix = $this->globalPrefix;
141
+
142
+        // Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
143
+        $instanceid = \OCP\Server::get(SystemConfig::class)->getValue('instanceid');
144
+        $this->globalPrefix = hash('xxh128', $instanceid . implode('.', $this->serverVersion->getVersion()));
145
+        $closure($this);
146
+        $this->globalPrefix = $backupPrefix;
147
+    }
148
+
149
+    /**
150
+     * create a cache instance for storing locks
151
+     *
152
+     * @param string $prefix
153
+     * @return IMemcache
154
+     */
155
+    public function createLocking(string $prefix = ''): IMemcache {
156
+        $cache = new $this->lockingCacheClass($this->getGlobalPrefix() . '/' . $prefix);
157
+        if ($this->lockingCacheClass === Redis::class) {
158
+            if ($this->profiler->isEnabled()) {
159
+                // We only support the profiler with Redis
160
+                $cache = new ProfilerWrapperCache($cache, 'Locking');
161
+                $this->profiler->add($cache);
162
+            }
163
+
164
+            if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
165
+                $cache = new LoggerWrapperCache($cache, $this->logFile);
166
+            }
167
+        }
168
+        return $cache;
169
+    }
170
+
171
+    /**
172
+     * create a distributed cache instance
173
+     *
174
+     * @param string $prefix
175
+     * @return ICache
176
+     */
177
+    public function createDistributed(string $prefix = ''): ICache {
178
+        $cache = new $this->distributedCacheClass($this->getGlobalPrefix() . '/' . $prefix);
179
+        if ($this->distributedCacheClass === Redis::class) {
180
+            if ($this->profiler->isEnabled()) {
181
+                // We only support the profiler with Redis
182
+                $cache = new ProfilerWrapperCache($cache, 'Distributed');
183
+                $this->profiler->add($cache);
184
+            }
185
+
186
+            if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
187
+                $cache = new LoggerWrapperCache($cache, $this->logFile);
188
+            }
189
+        }
190
+        return $cache;
191
+    }
192
+
193
+    /**
194
+     * create a local cache instance
195
+     *
196
+     * @param string $prefix
197
+     * @return ICache
198
+     */
199
+    public function createLocal(string $prefix = ''): ICache {
200
+        $cache = new $this->localCacheClass($this->getGlobalPrefix() . '/' . $prefix);
201
+        if ($this->localCacheClass === Redis::class) {
202
+            if ($this->profiler->isEnabled()) {
203
+                // We only support the profiler with Redis
204
+                $cache = new ProfilerWrapperCache($cache, 'Local');
205
+                $this->profiler->add($cache);
206
+            }
207
+
208
+            if ($this->logFile !== '' && is_writable(dirname($this->logFile)) && (!file_exists($this->logFile) || is_writable($this->logFile))) {
209
+                $cache = new LoggerWrapperCache($cache, $this->logFile);
210
+            }
211
+        }
212
+        return $cache;
213
+    }
214
+
215
+    /**
216
+     * check memcache availability
217
+     *
218
+     * @return bool
219
+     */
220
+    public function isAvailable(): bool {
221
+        return $this->distributedCacheClass !== self::NULL_CACHE;
222
+    }
223
+
224
+    public function createInMemory(int $capacity = 512): ICache {
225
+        return new CappedMemoryCache($capacity);
226
+    }
227
+
228
+    /**
229
+     * Check if a local memory cache backend is available
230
+     *
231
+     * @return bool
232
+     */
233
+    public function isLocalCacheAvailable(): bool {
234
+        return $this->localCacheClass !== self::NULL_CACHE;
235
+    }
236
+
237
+    public function clearAll(): void {
238
+        $this->createLocal()->clear();
239
+        $this->createDistributed()->clear();
240
+        $this->createLocking()->clear();
241
+        $this->createInMemory()->clear();
242
+    }
243 243
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -124,8 +124,8 @@  discard block
 block discarded – undo
124 124
 
125 125
 			// Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
126 126
 			$instanceid = $config->getValue('instanceid');
127
-			$installedApps = implode(',', array_keys($versions)) . implode(',', array_values($versions));
128
-			$this->globalPrefix = hash('xxh128', $instanceid . $installedApps);
127
+			$installedApps = implode(',', array_keys($versions)).implode(',', array_values($versions));
128
+			$this->globalPrefix = hash('xxh128', $instanceid.$installedApps);
129 129
 		}
130 130
 		return $this->globalPrefix;
131 131
 	}
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
 
142 142
 		// Include instanceid in the prefix, in case multiple instances use the same cache (e.g. same FPM pool)
143 143
 		$instanceid = \OCP\Server::get(SystemConfig::class)->getValue('instanceid');
144
-		$this->globalPrefix = hash('xxh128', $instanceid . implode('.', $this->serverVersion->getVersion()));
144
+		$this->globalPrefix = hash('xxh128', $instanceid.implode('.', $this->serverVersion->getVersion()));
145 145
 		$closure($this);
146 146
 		$this->globalPrefix = $backupPrefix;
147 147
 	}
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
 	 * @return IMemcache
154 154
 	 */
155 155
 	public function createLocking(string $prefix = ''): IMemcache {
156
-		$cache = new $this->lockingCacheClass($this->getGlobalPrefix() . '/' . $prefix);
156
+		$cache = new $this->lockingCacheClass($this->getGlobalPrefix().'/'.$prefix);
157 157
 		if ($this->lockingCacheClass === Redis::class) {
158 158
 			if ($this->profiler->isEnabled()) {
159 159
 				// We only support the profiler with Redis
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
 	 * @return ICache
176 176
 	 */
177 177
 	public function createDistributed(string $prefix = ''): ICache {
178
-		$cache = new $this->distributedCacheClass($this->getGlobalPrefix() . '/' . $prefix);
178
+		$cache = new $this->distributedCacheClass($this->getGlobalPrefix().'/'.$prefix);
179 179
 		if ($this->distributedCacheClass === Redis::class) {
180 180
 			if ($this->profiler->isEnabled()) {
181 181
 				// We only support the profiler with Redis
@@ -197,7 +197,7 @@  discard block
 block discarded – undo
197 197
 	 * @return ICache
198 198
 	 */
199 199
 	public function createLocal(string $prefix = ''): ICache {
200
-		$cache = new $this->localCacheClass($this->getGlobalPrefix() . '/' . $prefix);
200
+		$cache = new $this->localCacheClass($this->getGlobalPrefix().'/'.$prefix);
201 201
 		if ($this->localCacheClass === Redis::class) {
202 202
 			if ($this->profiler->isEnabled()) {
203 203
 				// We only support the profiler with Redis
Please login to merge, or discard this patch.