Глобальний контекст запиту - антидіаграма?


12

Я говорив сьогодні з моїм колегою про веб-рамки Python та наші враження про них. Я сказав йому, що я думаю, що Flask з глобальним запитом погано пахне і є антидією.

У документах говорять про контекст запиту:

На відміну від цього, під час обробки запиту існує кілька інших правил:

  • поки запит активний, локальні об'єкти контексту (flask.request та інші) вказують на поточний запит.
  • будь-який код може отримати цей об'єкт у будь-який час.

Я думаю, що я розумію ідею цього дизайнерського рішення - зробити додаток більш простим. Це просто компроміс, як у випадку з місцевими жителями теми :

Так, зазвичай не така яскрава ідея використовувати місцеві локальні мережі. Вони створюють неприємності для серверів, які не засновані на концепції потоків, і ускладнюють великі програми для обслуговування. Однак Flask просто не призначений для великих додатків або асинхронних серверів. Фляжка хоче зробити швидко та просто написати традиційну веб-програму.

Чи виправлення глобального об'єкта поточною інформацією запиту є анти-шаблоном?

Я вважаю, що це так, адже це, на думку аналізатора статичного коду, глобальний стан, хоча це не так. І я як програміст не зрозумію, як це працює, не уважно читаючи документи . І це має наслідки на тестах .

Чи не є хорошою практикою передавати запит як аргумент поглядам? Я думаю, що це більш читабельне, явне і простіше налагодження. І уникає глобальної держави.


2
Ви насправді не заявляли, які конкретні негативні наслідки такого антипатріума можуть бути. Я недовіряю широким загалам, які не мають фактичної основи.
Роберт Харві

2
Хороше запитання, але, на жаль, не багато якісних відповідей
сонливий

Відповіді:


4

Багато веб-рамок мають таку саму структуру: глобальний запит. У певному сенсі це правильно зробити, тому що, ей, насправді є лише один запит за раз.

То чи є сенс передавати запит навколо як параметр? Ні. Запит - це запит, а параметри призначені для передачі різних речей у різний час.

Реальна проблема виникає , як ви починаєте розглядати більш низькі рівні більшого додатки. З глобальним запитом виникає спокуса написати код у всьому місці, яке звертається до цього запиту в усьому світі. Це дуже погана річ . Це створює з'єднання між різними частинами коду, ускладнює зміни речей і ускладнює тестування речей.

Тому моя відповідь: зберігайте глобальний запит і живіть з ним. Однак там, де окремий модуль або функція не потребує всього запиту, передайте лише ті дані, які йому потрібні, як параметр. Введіть у свою функцію лише реферала, або URL, або командний хвіст та будь-які біти. Це допоможе зберегти код модульним, зменшить з'єднання та покращить встановленість.

Для крихітних програм це навряд чи має значення, але для більших програм це може бути справжнім рятівником.


3

(Я збираюся набратися сміливості і зроблю це відповіддю, хоча, можливо, я отримаю кілька голосів.)

Колба - мікрорамка; ви користуєтеся простотою, відмовляючись від надмірностей. Хоча на рівні кишок я згоден з вами, я знаю, що в одному магазині я використовував колбу + пушоловку, щоб дати мені багаторядність, яка мені потрібна. Це спрацювало дуже добре. Кожен екземпляр сценарію просто передав один запит (тобто одну нитку), і gunicorn обробляв "вентилятор" серед декількох потоків. Це було чудово в цьому.

Тож сприйнятий вами недолік, який ви відчуваєте - що кілька потоків можуть претендувати на глобальний стан - просто не проблема, тому що це один сценарій на потік.

(Ось де я можу зіткнутися з проблемою) Нитки та паралельність просто відрізняються у світі Python, і якщо ви приїжджаєте до неї з думкою Java, важко її втиснути. Мій досвід полягав у тому, що проблеми з одночасністю, які я брав за надані в Java, або які прозоро обробляються контейнером додатків, набагато ближче до поверхні в Python.

Мені було дивно, що один потік буде обробляти один виклик мого сценарію, але після того, як я одночасно пробіг декілька десятків, я почував себе краще.


4
Я не переживаю за безпеку ниток і таке. Я вважаю, що колба добре працює в цих випадках. Моє запитання щодо дизайну та архітектури додатків. Чи не є хорошою практикою передавати запит як аргумент поглядам? Я думаю, що це більш читабельне, явне і простіше налагодження.
warvariuc

2

У Python у вас є printкоманда (функція з v3), яка друкує до стандартного виводу. Ви не вказуєте прямо, що хочете надрукувати в STDOUT - це робиться для вас неявно поза кадром.

Безслідно. У Python. І з цим ніхто не має проблем. Чому?

printє частиною мови Python, і однією з вимог програмування в Python є ... добре ... знаючи Python. І якщо ви знаєте Python, ви знаєте, що printнацілений на STDOUT. Ніяких сюрпризів там немає.

Python - як мова - може визначити власну умовність і припустити, що програмісти їх знають.

Рамки також користуються цією привілеєм - ось одна з ключових відмінностей між рамками та бібліотекою. Вам не доведеться вивчати бібліотеку, щоб користуватися нею - просто потрібно знайти ту частину API, яка вам потрібна, і припустити, що вона відповідає умовам мови (або фреймворку). Тому ви не бачите рекрутерів, які шукають людей із знаннями в GSON або Apache Commons. Але ви бачите рекрутерів, які шукають людей з досвідом роботи з JQuery або Ruby on Rails або ASP.NET MVC - адже це рамки, які визначають власні умови, які вам потрібно вивчити та знати.

Колба, як рамка, може визначити умову для зберігання контексту в глобальному потоці локальних мереж - і це не повинно нікого дивувати, тому це не антидіаграма.


2
Зауважте, що "stdout" означає те, на що вказується дескриптор файлу sys.stdout. Якщо це змінити, друк переходить в інше місце.
Фоши

1
Крім того, ви можете змінити вихідний потік, використовуючи >>оператор або передаючи fileаргумент для printфункціонування в Python3. Отже, sys.stdoutце лише значення за замовчуванням, яке може бути замінено.
Варварюк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.