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:
parent
362b4cbc0c
commit
02f0952f9c
|
@ -16,26 +16,9 @@
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import connection, transaction
|
|
||||||
from django.utils.text import slugify
|
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):
|
def generate_slug(name, seen_slugs=None, max_length=256):
|
||||||
base_slug = slugify(name).lstrip('_')
|
base_slug = slugify(name).lstrip('_')
|
||||||
slug = base_slug[:max_length]
|
slug = base_slug[:max_length]
|
||||||
|
|
|
@ -15,42 +15,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# authentic2
|
# authentic2
|
||||||
|
|
||||||
import threading
|
from authentic2.utils.models import generate_slug
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
def test_generate_slug():
|
def test_generate_slug():
|
||||||
|
|
Loading…
Reference in New Issue