تفاوت دو تکه کد زیر که از Django channels استفاده کرده است چیست؟
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class FeedbackLockConsumer(WebsocketConsumer): def websocket_connect(self, event): doc_id = self.scope['url_route']['kwargs']['doc_id'] user = self.scope['user'] async_to_sync(self.channel_layer.group_add)( f"group_doc_{doc_id}", self.channel_name ) self.accept() self.send( text_data=json.dumps({"message": "You are the Editor"}) ) |
و
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class FeedbackLockConsumer(AsyncWebsocketConsumer): async def websocket_connect(self, event): doc_id = self.scope['url_route']['kwargs']['doc_id'] user = self.scope['user'] await self.channel_layer.group_add( f"group_doc_{doc_id}", self.channel_name ) await self.accept() await self.send( text_data=json.dumps({"message": "You are the Editor"}) ) |
هر دو کد consumer هایی برای برقراری ارتباط websocket هستند. در اولی از ارتباط sync استفاده شده و در دومی از ارتباط async استفاده شده است.
در نتیجه:
در اولی:
اگر یک کانکشن برقرار شود، دیگر هیچ کانکشنی برقرار نمیشود تا کانکشن اولی بسته شود. چون کانکشن اول accept شده و هر کانکشن یک worker thread رو اشغال میکنه و تا زمانی که بسته نشه thread برای کانکشن بعدی باز نمیشه. این روش برای کارهای سریع مثل یه ارتباط با دیتابیس مناسب است اما برای یک ارتباط websocket که قرار است مدت زیادی باز بماند خوب نیست.
در دومی:
ارتباطات async است یعنی در واقع به آن گفته می شود که در قسمت await منتظر بمان تا I/O تکمیل شود اما در طول این انتظار ارتباطات دیگر می توانند برقرار شوند. در این حالت هر ارتباط به صورت یک task در event loop اجرا میشود. event loop ارتباطات دیگر را مدیریت میکند.
در واقع در حالت sync تسکها توسط worker ها انجام میشود و در حالت async تسک ها توسط event loop.
حالت sync مانند آشپزیست که هر قسمت غذا را کامل می پزد و بعد سراغ قسمت بعدی می رود اما حالت async چند ماهیتابه جلوی آشپز است که هر کدام را می چرخاند و سراغ بعدی می رود. این کار را event loop انجام می دهد که در پایتون در asyncio پیاده سازی شده است.
در دو consumer ای که نوشته شد هم داستان همین است. تا کانکشن اول بسته شود کانکشن بعدی باز نمی شود اما در حالت async این طور نیست و کانکشن اول در قسمت await وای میسه و event loop سراغ کانکشن های بعدی می رود.

کی از Message Queue استفاده میکنیم؟ وقتی که قرار باشد پیامی بین process ها یا consumer ها جابجا شوند. در واقع هر وقت توی django channels از channel layer بخایم استفاده کنیم باید از message q استفاده کنیم. در واقع channel layer همان message queue است.