Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 755999ea authored by Ronak Patel's avatar Ronak Patel
Browse files

reduce memory usage by avoiding the UserManager's local cache

parent e7cef1fb
Loading
Loading
Loading
Loading
+54 −11
Original line number Diff line number Diff line
@@ -123,11 +123,16 @@ class RecoveryWarningNotificationCommand extends Command {

			// Initialize arrays
			$this->uids = [];
			// Only initialize disable/delete arrays if the options are set
			if ($disableAccounts) {
				$this->disableUids = [];
			}
			if ($deleteAccounts) {
				$this->deleteUids = [];
			}

			// Process users
			$this->identifyUnverifiedUsers($output);
			$this->identifyUnverifiedUsers($output, $disableAccounts, $deleteAccounts);
			$this->sendNotificationsAndEmails($output);
			
			if ($disableAccounts) {
@@ -143,8 +148,12 @@ class RecoveryWarningNotificationCommand extends Command {

			$output->writeln('<info>[' . $endTime . '] === Command Summary ===</info>');
			$output->writeln('  - Users for notifications: ' . count($this->uids));
			if ($disableAccounts) {
				$output->writeln('  - Users for disable: ' . count($this->disableUids));
			}
			if ($deleteAccounts) {
				$output->writeln('  - Users for deletion: ' . count($this->deleteUids));
			}
			$output->writeln('  - Total execution time: ' . round($overallDuration, 2) . 's');

			$output->writeln('<info>[' . $endTime . '] Recovery warning notification command completed successfully.</info>');
@@ -159,8 +168,30 @@ class RecoveryWarningNotificationCommand extends Command {
	}


	/**
	 * Get user object without caching to avoid memory accumulation
	 * Uses getBackends to walk through all backends and get user with caching disabled
	 * 
	 * @param string $username The username to retrieve
	 * @return \OCP\IUser|null The user object or null if not found
	 */
	private function getUser(string $username) {
		$backends = $this->userManager->getBackends();
		
		foreach ($backends as $backend) {
			if ($backend->userExists($username)) {
				// Use getUserObject with cacheUser = false to avoid caching
				// This prevents the user object from being stored in the manager's cache
				return $this->userManager->getUserObject($username, $backend, false);
			}
		}
		
		return null;
	}

	private function identifyUnverifiedUsers(OutputInterface $output, bool $checkDisable = false, bool $checkDelete = false): void {
		$identificationStart = microtime(true);
		
	private function identifyUnverifiedUsers(OutputInterface $output): void {
		$users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', '');
		if (!is_array($users)) {
			$output->writeln('<error>Error: Expected array for recovery-email users, got ' . gettype($users) . '</error>');
@@ -181,7 +212,7 @@ class RecoveryWarningNotificationCommand extends Command {

		foreach ($users as $username) {
			try {
				$user = $this->userManager->get($username);
				$user = $this->getUser($username);
				
				if (!$user) {
					$invalidCount++;
@@ -240,8 +271,13 @@ class RecoveryWarningNotificationCommand extends Command {
					$this->uids[] = $uid;
				}

				// Only check for disable/delete if the options are set
				if ($checkDisable) {
					$this->identifyForDisable($user, $age);
				}
				if ($checkDelete) {
					$this->identifyForDelete($user, $age);
				}
				
				$disabledAtTimestamp = strtotime($existingDisableDate);
				$deleteDate = date('Y-m-d', $disabledAtTimestamp + ($this->deleteUserAfterDisableDays * 24 * 60 * 60));
@@ -264,6 +300,8 @@ class RecoveryWarningNotificationCommand extends Command {
			}
		}
		
		$identificationDuration = microtime(true) - $identificationStart;
		
		$output->writeln('<info>User processing summary:</info>');
		$output->writeln('  - Total users: ' . count($users));
		$output->writeln('  - Processed: ' . $processedCount);
@@ -272,9 +310,14 @@ class RecoveryWarningNotificationCommand extends Command {
		$output->writeln('  - Invalid: ' . $invalidCount);
		$output->writeln('  - Errors: ' . $errorCount);
		$output->writeln('  - For notifications: ' . count($this->uids));
		if ($checkDisable) {
			$output->writeln('  - For disable: ' . count($this->disableUids));
		}
		if ($checkDelete) {
			$output->writeln('  - For deletion: ' . count($this->deleteUids));
		}
		$output->writeln('  - Identification time: ' . round($identificationDuration, 2) . 's');
	}

	private function identifyForDisable($user, int $age): void {
		if ($age >= $this->disableUserAfterUnverifiedDays) {