misc: delete unused safe_get_or_create (#64485)

Introduced in #60658 it used a global lock on model's table to prevent
multiple access, using the Lock model is simpler and more efficient.
This commit is contained in:
Benjamin Dauvergne 2022-04-22 18:21:47 +02:00
parent 362b4cbc0c
commit 02f0952f9c
2 changed files with 1 additions and 53 deletions

View File

@ -16,26 +16,9 @@
import itertools
from django.conf import settings
from django.db import connection, transaction
from django.utils.text import slugify
def safe_get_or_create(model, defaults=None, **kwargs):
assert (
getattr(settings, 'TESTING', False) or not connection.in_atomic_block
), 'safe_get_or_create cannot be used in inside a transaction'
try:
return model.objects.get(**kwargs), False
except model.DoesNotExist:
pass
with transaction.atomic():
with connection.cursor() as cur:
cur.execute('LOCK TABLE "%s" IN EXCLUSIVE MODE' % model._meta.db_table)
return model.objects.get_or_create(defaults=defaults, **kwargs)
def generate_slug(name, seen_slugs=None, max_length=256):
base_slug = slugify(name).lstrip('_')
slug = base_slug[:max_length]

View File

@ -15,42 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# authentic2
import threading
from django.db import connection
from authentic2.custom_user.models import User
from authentic2.utils.models import generate_slug, safe_get_or_create
def test_safe_get_or_create(transactional_db, concurrency):
EMAIL = 'john.doe@example.net'
barrier = threading.Barrier(concurrency)
users = []
exceptions = []
threads = []
def thread_run():
try:
barrier.wait()
user, created = safe_get_or_create(User, email=EMAIL, defaults={'email': EMAIL})
except Exception as e:
exceptions.append(e)
else:
if created:
users.append(user)
finally:
connection.close()
for _ in range(concurrency):
threads.append(threading.Thread(target=thread_run))
threads[-1].start()
for thread in threads:
thread.join()
assert not exceptions
assert len(users) == 1
assert User.objects.count() == 1
users[0].delete()
from authentic2.utils.models import generate_slug
def test_generate_slug():