我通過 API 在我的 Django 應用程式中收到通知,我應該在 500 毫秒之前回傳 HTTP 200。為了實作這一點,我應該異步運行相關的任務。我正在使用asgiref庫,一切運行正常,但我認為實際上并沒有異步運行。
主要觀點
在此視圖中,我收到通知。我設定了 2 個列印點來檢查服務器日志中的計時。
@csrf_exempt
@api_view(('POST',))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def IncommingMeliNotifications(request):
print('--------------------------- Received ---------------------')
notificacion = json.loads(request.body)
call_resource = async_to_sync(CallResource(notificacion))
print('--------------------------- Answered ---------------------')
return Response({}, template_name='assessments.html', status=status.HTTP_200_OK)
次要視圖
收到通知后,我呼叫了輔助視圖CallResource,我希望它異步運行。
def CallResource(notificacion):
do things inside....
print('--------------------------- Secondary view ---------------------')
return 'ok'
記錄結果
當我檢查日志時,我總是按以下順序列印:
print('--------------------------- Received ---------------------')
print('--------------------------- Secondary view ---------------------')
print('--------------------------- Answered ---------------------')
但我想Secondary view應該是最后列印的,因為:
print('--------------------------- Received ---------------------')
print('--------------------------- Answered ---------------------')
print('--------------------------- Secondary view ---------------------')
我在這里缺少什么?
我正在閱讀檔案github.com/django/asgiref,據我所知,這應該是我正在研究的范式:
如果程式的最外層是同步的,那么所有通過 AsyncToSync 運行的異步代碼將在任意子執行緒中的每次呼叫事件回圈中運行,而所有 thread_sensitive 代碼將在主執行緒中運行。
歡迎任何線索。提前致謝。
uj5u.com熱心網友回復:
async_to_sync 讓同步執行緒停止并等待異步函式,而不是異步運行同步函式。
運行異步任務
- 由于您沒有提到 ASGI 服務器,看來您正在運行同步開發服務器
python manage.py runserver。
如果是這樣,請安裝并運行Daphne(來自 Django)。
pip install daphne
daphne myproject.asgi:application
如果您使用的是 Django 3.x 及更高版本,那么在您的 wsgi.py 檔案所在的目錄中應該已經有一個 asgi.py 檔案。請參閱docs.djangoproject.com/en/3.2/howto/deployment/asgi/。
如果您使用的是 Django 2.x 及以下版本,請升級到 Django 3.x 及以上版本并創建 asgi.py 檔案。請參閱如何為現有專案生成 asgi.py?.
- 您可以在運行 ASGI 服務器時創建異步任務。
# call_resource = async_to_sync(CallResource(notificacion))
loop = asyncio.get_event_loop()
task = loop.create_task(CallResource(notificacion))
- 異步函式應該用
async def.
# def CallResource(notificacion):
async def CallResource(notificacion):
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/346712.html
