Make namespace deletion asynchronous
Instead of deleting a namespace synchronously as before, we now mark the namespace for deletion, disable it, and rename it. A worker then comes along and deletes the namespace in the background. This results in a *significantly* better user experience, as the namespace deletion operation now "completes" in under a second, where before it could take 10s of minutes at the worse. Fixes https://jira.coreos.com/browse/QUAY-838
This commit is contained in:
parent
d9015a1863
commit
8bc55a5676
21 changed files with 244 additions and 129 deletions
|
@ -4,9 +4,11 @@ import pytest
|
|||
|
||||
from mock import patch
|
||||
|
||||
from data.database import EmailConfirmation
|
||||
from data.database import EmailConfirmation, User, DeletedNamespace
|
||||
from data.model.user import create_user_noverify, validate_reset_code, get_active_users
|
||||
from data.model.user import mark_namespace_for_deletion, delete_namespace_via_marker
|
||||
from util.timedeltastring import convert_to_timedelta
|
||||
from data.queue import WorkQueue
|
||||
from test.fixtures import *
|
||||
|
||||
def test_create_user_with_expiration(initialized_db):
|
||||
|
@ -38,3 +40,46 @@ def test_get_active_users(disabled, initialized_db):
|
|||
for user in users:
|
||||
if not disabled:
|
||||
assert user.enabled
|
||||
|
||||
def test_mark_namespace_for_deletion(initialized_db):
|
||||
def create_transaction(db):
|
||||
return db.transaction()
|
||||
|
||||
# Create a user and then mark it for deletion.
|
||||
user = create_user_noverify('foobar', 'foo@example.com', email_required=False)
|
||||
|
||||
# Mark the user for deletion.
|
||||
queue = WorkQueue('testgcnamespace', create_transaction)
|
||||
mark_namespace_for_deletion(user, [], queue)
|
||||
|
||||
# Ensure the older user is still in the DB.
|
||||
assert User.get(id=user.id).username != 'foobar'
|
||||
|
||||
# Ensure we can create a user with the same namespace again.
|
||||
new_user = create_user_noverify('foobar', 'foo@example.com', email_required=False)
|
||||
assert new_user.id != user.id
|
||||
|
||||
# Ensure the older user is still in the DB.
|
||||
assert User.get(id=user.id).username != 'foobar'
|
||||
|
||||
|
||||
def test_delete_namespace_via_marker(initialized_db):
|
||||
def create_transaction(db):
|
||||
return db.transaction()
|
||||
|
||||
# Create a user and then mark it for deletion.
|
||||
user = create_user_noverify('foobar', 'foo@example.com', email_required=False)
|
||||
|
||||
# Mark the user for deletion.
|
||||
queue = WorkQueue('testgcnamespace', create_transaction)
|
||||
marker_id = mark_namespace_for_deletion(user, [], queue)
|
||||
|
||||
# Delete the user.
|
||||
delete_namespace_via_marker(marker_id, [])
|
||||
|
||||
# Ensure the user was actually deleted.
|
||||
with pytest.raises(User.DoesNotExist):
|
||||
User.get(id=user.id)
|
||||
|
||||
with pytest.raises(DeletedNamespace.DoesNotExist):
|
||||
DeletedNamespace.get(id=marker_id)
|
||||
|
|
Reference in a new issue