#36439: Auth hashing blocks event loop if using asyncio -------------------------------------+------------------------------------- Reporter: robertaistleitner | Type: | Cleanup/optimization Status: new | Component: | contrib.auth Version: 5.1 | Severity: Normal Keywords: async, auth, | Triage Stage: asyncio, performance | Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- To a large extent, issues with auth in async auth has been fixed in https://github.com/django/django/commit/50f89ae850f6b4e35819fe725a08c7e579bfd099, I guess this is the last part of proper async implementation of authentication.
There exist custom implementations for asyncio regarding checking a password using the configured hashers which can be found in https://github.com/django/django/blob/68c9f7e0b79168007e6ba0139fd315d7c44ca8c9/django/contrib/auth/hashers.py#L86-L91. This implementation has a flaw because the CPU heavy calculation of the hash is blocking the event loop of asyncio, causing the whole server to stall and queueing up all the following authentications that may rush in in case of heavy load. My proposal is to use a ThreadPoolExecutor here to be able to unload the work from the event loop: {{{ CHECK_PASSWORD_THREAD_POOL_EXECUTOR = ThreadPoolExecutor(16) async def acheck_password(password, encoded, setter=None, preferred="default"): """See check_password().""" # verify_password is cpu heavy and needs to be executed in a separate thread to not block a running asyncio event loop is_correct, must_update = await sync_to_async( verify_password, thread_sensitive=False, executor=CHECK_PASSWORD_THREAD_POOL_EXECUTOR )(password, encoded, preferred=preferred) if setter and is_correct and must_update: await setter(password) return is_correct }}} The number of available thread could be exposed via setting, or skipped altogether by using a new thread on each verify_password call. What are your thoughts on this? -- Ticket URL: <https://code.djangoproject.com/ticket/36439> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/django-updates/010701973f3b447a-e72844a3-af90-4e4b-9d83-6c3cbf2050e7-000000%40eu-central-1.amazonses.com.