Skip to content

Commit d1d3cd8

Browse files
committed
feat: Use PhpDumpCache in Console/Application to avoid loading all commmands
This saves 100ms on occ runs by avoiding to load all commands to only run one of them. The list of commands is cached and loading is skipped when command is known. Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
1 parent 80f5d99 commit d1d3cd8

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

lib/private/Console/Application.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use ArgumentCountError;
1212
use OC\MemoryInfo;
1313
use OC\NeedsUpdateException;
14+
use OC\PhpDumpCache;
1415
use OC\SystemConfig;
1516
use OCP\App\AppPathNotFoundException;
1617
use OCP\App\IAppManager;
@@ -43,6 +44,7 @@ public function __construct(
4344
private MemoryInfo $memoryInfo,
4445
private IAppManager $appManager,
4546
private Defaults $defaults,
47+
private PhpDumpCache $dumpCache,
4648
) {
4749
$this->application = new SymfonyApplication($defaults->getName(), $serverVersion->getVersionString());
4850
}
@@ -83,11 +85,11 @@ public function loadCommands(
8385
}
8486

8587
try {
86-
require_once __DIR__ . '/../../../core/register_command.php';
8788
if ($this->config->getSystemValueBool('installed', false)) {
8889
if (Util::needUpgrade()) {
8990
throw new NeedsUpdateException();
9091
} elseif ($this->config->getSystemValueBool('maintenance')) {
92+
require_once __DIR__ . '/../../../core/register_command.php';
9193
if ($this->appManager->isEnabledForAnyone('app_api')) {
9294
// AppAPI must stay usable during maintenance mode;
9395
// loading commands from register_command.php is intentionally skipped.
@@ -106,6 +108,16 @@ public function loadCommands(
106108
}
107109
$this->writeMaintenanceModeInfo($input, $output);
108110
} else {
111+
$cachedCommandList = $this->dumpCache->loadCache([self::class]);
112+
if (is_array($cachedCommandList)) {
113+
$firstArg = $input->getArgument('command');
114+
if ($firstArg !== null && isset($cachedCommandList[$firstArg])) {
115+
$this->appManager->loadApps();
116+
$this->application->add(Server::get($cachedCommandList[$firstArg]));
117+
return;
118+
}
119+
}
120+
require_once __DIR__ . '/../../../core/register_command.php';
109121
$this->appManager->loadApps();
110122
foreach ($this->appManager->getEnabledApps() as $app) {
111123
try {
@@ -150,6 +162,9 @@ public function loadCommands(
150162
}
151163
}
152164

165+
/* To cover branches from above if that skipped register_command */
166+
require_once __DIR__ . '/../../../core/register_command.php';
167+
153168
if ($input->getFirstArgument() !== 'check') {
154169
$errors = \OC_Util::checkServer(Server::get(SystemConfig::class));
155170
if (!empty($errors)) {
@@ -161,6 +176,19 @@ public function loadCommands(
161176
throw new \Exception('Environment not properly prepared.');
162177
}
163178
}
179+
$commands = $this->application->all();
180+
$cache = [];
181+
foreach ($commands as $command) {
182+
$name = $command->getName();
183+
if ($name !== null) {
184+
$cache[$name] = $command::class;
185+
}
186+
187+
foreach ($command->getAliases() as $alias) {
188+
$cache[$alias] = $command::class;
189+
}
190+
}
191+
$this->dumpCache->saveCache([self::class], $cache);
164192
}
165193

166194
/**

0 commit comments

Comments
 (0)