Saturday, March 26, 2011

Deleting a member from a large site

The other day my client complained about not being able to delete a member from his site. When I tried it, each time it would spin around for a while and then the zeo client would die with ClientDisconnected. When I poked into the code, i discovered that every object in the site was being visited and reindexed in order to clear out any local roles that the member may have on the object. Of course the transaction becomes huge and the zeo client runs out of memory and ends up disconnecting from the server.

So I added a transaction.commit() in the body of the deleteLocalRoles function in MembershipTool.py. This helped somewhat. The zeo client did not run out of memory and was able to stay connected. Although I ended up with a proxy timeout at the browser, Plone was able to plod along and delete the member and when I went back into User and Groups management, the member was gone.

But nobody likes this half-baked "fix" as you can see at

http://www.gossamer-threads.com/lists/zope/cmf/230407

3 comments:

  1. If you have a site with a large amount of content (and even if you don't), it's generally best to delegate local roles to groups rather than users. Doing so avoids this issue entirely, unless for some strange reason you need to delete a group that had local role assignments.

    Committing full transactions in the middle of an operation like that can have disastrous results in terms of database consistency.

    ReplyDelete
  2. But even if I did, MembershipTool.py won't know
    :-)

    It will merrily continue to load every content object in my site and attempt delete even non-existent local roles and then reindex security on the object AFAICS.

    ReplyDelete
  3. The cleanup after user deletion is a typical task that could be delegated to a maintenance process that would happen asynchronously. There is no need for this to be handled inside the same transaction as long as it actually happens.

    Introducing arbitrary commits is not the way to solve issues like this — but we should start thinking of ways to handle this type of challenge. Plone.app.asynch has some potential in this regard…

    ReplyDelete