- Affected version
- 2.2.13
This is a rather complicated bug, but I hope it's understandable.
Method
After deletion,. those jobs are enqueued in method
Job
Job
Now finally service
The overall effect of this call chain is that content is changed twice:
This is inefficient and can cause quite some performance issues as noted in
In case a user account is renamed before deletion there should be only one content change:
Update userid to 0 and set username to $newUsername
Method
XF\Service\User\Delete::delete
sets entity options to avoid running jobs XF:UserRenameCleanup
and XF:UserDeleteCleanup
when renaming a user before deletion:
PHP:
if ($this->renameTo)
{
$user->reset();
$user->setOption('admin_edit', true);
$user->setOption('enqueue_rename_cleanup', false);
$user->setOption('enqueue_delete_cleanup', false);
$user->set('username', $this->renameTo);
After deletion,. those jobs are enqueued in method
runPostDeleteJobs
PHP:
if ($this->renameTo)
{
$jobList = [
[
'XF:UserRenameCleanUp',
[
'originalUserId' => $user->user_id,
'originalUserName' => $this->originalUserName,
'newUserName' => $this->renameTo
]
],
[
'XF:UserDeleteCleanUp',
[
'userId' => $user->user_id,
'username' => $this->renameTo
]
]
];
$this->app->jobManager()->enqueueUnique('userRenameDelete' . $user->user_id, 'XF:Atomic', [
'execute' => $jobList
]);
Job
XF:UserRenameCleanUp
calls service XF:User\ContentChange
in method run
PHP:
/** @var \XF\Service\User\ContentChange $contentChanger */
$contentChanger = $this->app->service(
'XF:User\ContentChange', $this->data['originalUserId'], $this->data['originalUserName']
);
$contentChanger->setupForNameChange($this->data['newUserName']);
$contentChanger->restoreState($this->data['currentStep'], $this->data['lastOffset']);
$result = $contentChanger->apply($maxRunTime);
Job
XF:UserDeleteCleanUp
calls service XF:User\DeleteCleanUp
in method run
PHP:
$deleter = $this->app->service(
'XF:User\DeleteCleanUp', $this->data['userId'], $this->data['username']
);
$deleter->restoreState($this->data['currentStep'], $this->data['lastOffset']);
$result = $deleter->cleanUp($maxRunTime);
Now finally service
XF:User\DeleteCleanUp
calls service XF:User\ContentChange
in method stepChangeOwne
PHP:
$contentChanger = $this->service('XF:User\ContentChange', $this->userId, $this->userName);
$contentChanger->setupForDelete();
if (is_array($lastOffset))
{
list($changeStep, $changeLastOffset) = $lastOffset;
$contentChanger->restoreState($changeStep, $changeLastOffset);
}
$result = $contentChanger->apply($maxRunTime);
The overall effect of this call chain is that content is changed twice:
- First, only the username is changed to $newUsername via rename cleanup
- Afterwards the userid is changed to 0 via delete cleanup
This is inefficient and can cause quite some performance issues as noted in
XF 2.2 - Pruned 25k members and now the server is grinding to a halt
The initial processing ended an hours ago but the site is still being crushed. The jobs table has 20k entries for XF:UserDeleteCleanUp. Is it working through these or do I have a bigger problem? I am also getting the "There are scheduled jobs outstanding which have not run. Jobs may not be...
xenforo.com
XF 2.1 - Too many MySQL Processes "UPDATE ( SELECT content_id FROM xf_reaction_content WHERE content_type = ? AND reaction_"
I have a bunch of mySQL processes that looks like they are stuck and this is causing a high load on the server. Any idea?
xenforo.com
In case a user account is renamed before deletion there should be only one content change:
Update userid to 0 and set username to $newUsername
Last edited: