ermouth: (Default)
[personal profile] ermouth

Вот тут http://morfizm.livejournal.com/785439.html имеет место некоторая дискуссия по поводу запретов на использование каких-то приёмов, распространяемых на целую архитектуру.

morfizm вот предлагает увольнять тех, кто использует сетевые вызовы в ui-треде. Я его прекрасно понимаю – аутлюки до версии 2010 просто изобиловали глухими блокировками интерфейса на время сетевых операций, это невероятно бесило.

Но запрещать вообще сетевые вызовы из ui-тредов – это крутовато. Да и вообще формировать запреты, распространяющиеся на огромное количество заранее неизвестных случаев – очень опасное занятие, и вот почему.

1. Некомпетентность выносящего запреты. В большой системе нередко просто не существует человека, знающего всю систему в деталях. Поэтому даже располагая ворохом метрик вынести unbiased суждение о необходимости бесповоротных похорон какой-то большой фичи практически невозможно. Люди не делают осознанный выбор, нобелевка по экономике, 2002. И как раз наиболее неадекватные низкого уровня запреты обычно выносятся под трескучие рассуждения об архитектуре и других высоких материях.

2. Вместо запрета чаще всего достаточно разумного ограничения. Скажем, к рассматриваемому случаю очевидно подойдёт ограничение “таймаут сетевой операции в потоке ui не более 500мс”, например. Если мы не успели, выводим крутилку и повторяем запрос в другом потоке (асинхронно). Этот приём – не выдумка, так раньше вёл себя фотошоп.

3. Запреты долго распростряняются. И плохо контролируются. А уж если прижились – очень долго отмирают. В противовес – ограничения принимаются легче и снимаются тоже легче.

Тут есть ещё следствие – недальновидный запрет обязательно попробуют обойти, и это даже может стать систематической практикой. Просто начните набирать в гугле “как обойти запрет”.

4. Обрисовать систему нефрагментарно, используя запреты на технические приёмы как описательный аппарат, весьма сложно. Если по-русски – хрен к какой системе напишешь техзадание, описывая что система делать не должна вместо описания того, что и в каких рамках должна.

Это всё вышесказанное совершенно не отменяет необходимости хорошо проработанных архитектурного и инфраструктурного плана ограничений, “склоняющих писать правильно”. Но полное изгнание фичи из соображений абы чего не случилось – это крутовато.

Ещё на сопредельную тему – Соглашения vs конфигурации.

Date: 2013-03-16 10:52 pm (UTC)
From: [identity profile] morfizm.livejournal.com
Мне прям как-то неловко, что ты цитируешь на полном серьёзе, всё-таки в моём посте есть факт применения гиперболы, и под вынесенным из контекста "morfizm вот предлагает увольнять тех, кто использует сетевые вызовы в ui-треде" я бы не подписался.

Но у меня есть обоснованный strong opinion, так что мы можем поговорить. Если бы я делал свой продукт с нуля, я бы таки ввёл этот жёсткий запрет. Это небольшой overhead, но, как мне видится, в большинстве случаев он должен окупаться с лихвой. Исключения могут составлять системы, в которых многопоточность и асинхронные вызовы вообще невозможны, или сильно невыгодны, например, massive multiplayer games, или UI для финансовых новостей и трейдинга на бирже. Но в таких приложениях ограничения на задержки выставляются поддерживаются настолько строго, что проблему UX они таки решают эффективно.

Твои аргументы понятны. Давай для баланса добавлю своих:

1. Некомпетентность соблюдающего ограничения. В большой системе есть большая команда, и всегда есть люди, которые не способны или не хотят, или ленятся даже измерить performance impact of their changes. Всегда есть какой-то project deadline pressure, из-за которого захочется cut corners, даже если ты компетентен. В противовес этому, всегда есть один или несколько компетентных людей, присоединившихся к проекту на ранних стадиях, способных установить полезные жёсткие запреты.

2+3. Ограничения намного сложнее enforce'ить, чем запреты. Каждый может отследить следование запрету в code review. Чтобы отследить исполение ограничения, например, не более 500 мс на запрос, тебе нужно запускать массивные production-like тесты на огромных объёмах данных, и симулировать все эффекты production environment'а. Потому что исполнение запроса имеет случайную компоненту, время это не число, а это распределение. Ограничение на максимум ещё куда ни шло, но куда более часто используемое ограничение - ограничение на среднее или на 99.9 процентиль - это ограничение, которое нелегко проверить. Что сделать нелегко, то делать будут не всегда :) Отсюда дырки.

Ограничение вроде "timeout на 500мс для алгоритма #1 и fall-back к алгоритму #2" - это, по сути, жёсткий архитектурный запрет. Чтобы его заэнфорсить, тебе всё равно нужна жёсткая изоляция компонент, и в том узком перешейке, где UI использует алгоритм #1, там должен стоять один-единственный самый внешний timeout на 500мс, после чего вызов алгоритма #2. Подумай, это, ведь, на самом деле, очень жёсткое архитектурное ограничение само по себе. Не менее жёсткое чем "не использовать сетевые запросы вовсе".

4. Ну, вопрос терминологии. Вместо "запрет на сетевый вызовы" можно сказать "разрешение на вызовы с гарантированным максимальным временем исполнения". Сетевые вызовы практически сразу же автоматически исключаются. Кроме, пожалуй, твоего варианта с жёстким таймаутом и повтором в фоновом режиме в случае нарушения таймаута. Кстати, такой вариант может быть wasteful для сервера и для трафика, т.к. каждое нарушение это повтор. Если нарушений достаточно мало, это может быть приемлемо.

Date: 2013-03-16 10:56 pm (UTC)
From: [identity profile] morfizm.livejournal.com
Ещё - уточню. Под "неиспользованием сетевых запросов в UI" я имею в виду взаимодействие пользователя с какими-то стандартными UI-контролами. Если же речь идёт о кнопке "искать" и задержке между нажатием на эту кнопку и отображением результата поиска, или о переходе на другую страницу - это другое, потому что тут у пользователя есть совершенно ясное ожидание результатов долгой операции, и у него нет ожидания интерактивности пока результат не будет выполнен. Результат таких запросов тоже должен быть как-то ограничен (и тут таймаут это отлично), но то, про что я говорил - это другое. Это штуки вроде "открытие подменю", скроллинг, перемещение курсора на другой элемент списка, где справа refresh-ится панель с деталями и т.п. Если панель с деталями требует сетевого запроса, она должна рефрешиться в background'е, чтобы ты мог без тормозов переместить курсор на следующий элемент, если ты не хочешь ждать. Это очень важно жёстко enforce'ить, и именно из-за отсутствия такой дисциплины в Outlook'е некоторые письма отрисовываются по минуте на preview pane. Ты даже закрыть Outlook не можешь!

Date: 2013-03-17 01:44 am (UTC)
From: [identity profile] ermouth.livejournal.com
Я не то чтобы всерьёз, я скорее с некоторым сарказмом, просто смайликами не обозначил )

По поводу одного порядка "жесткости" я не согласен совершенно, и после раздумий тоже. Удаление куска функционала – это уменьшение мощности множества реализуемых фич. Конечная параметризация этого функционала мощность множества фич не снижает.

По поводу запретов на целый класс конструкций языка под флагом "это bad practice" – вот тут у меня была дискуссия в довольно жестких выражениях https://github.com/jquery/jquery/pull/1140#issuecomment-12889040. Там ситуация как раз под обсуждение. Контрибуторы jQuery прикрываясь тем, что не трогать прототипы – это их approach, взяли и фактически запретили использовать этот приём всем остальным.

И как обычно, быстро выяснилось что причина – "потому что гладиолус". Ребята там забыли, что стиль, введённый jQuery, 5 лет назад тоже считался bad practice – и ничего, пол-сети сейчас так делает.

Прекрасно, что тема всё же была переоткрыта и правки в код внесены. Упрись они и откажись – у меня уже был готов обходной вариант.
Edited Date: 2013-03-17 01:45 am (UTC)

Date: 2013-03-17 02:48 am (UTC)
From: [identity profile] ermouth.livejournal.com
Воот. То-есть в самом то деле нам надо жестко контролировать отклик интерфейса, причём весьма извилисто подстраиваясь под разные моменты, а не запрещать операции, которые потенциально могут навредить.

Это по мне как раз пример разумного ограничения. И вот его и надо выполнять, и тестами накрывать и тд.

Мастер-детэил кста может обладать ещё одним видом поведения. Если у тебя панель детэйла не предполагает полей ввода, её можно подновить уже отрисованную результатами уточняющего асинхронного запроса – подсветив те части, что обновились.

Date: 2013-03-21 04:49 am (UTC)
From: [identity profile] morfizm.livejournal.com
Я не то чтобы всерьёз, я скорее с некоторым сарказмом, просто смайликами не обозначил )

OK:)


Ну, твой поинт, в общем, понятен, он заслуживает внимания. Общие запреты можно сделать непродуманно/ошибочно, или же они устареют. On the positive side, их действительно легче энфорсить. Если бы в Outlook'е был запрет на любой синхронный network call, я как пользователь не потерял бы ни одной фичи, но избежал бы всех или почти всех зависаний Outlook'а, когда неудачное письмо отображается на preview pane.
Я всё ещё не вижу принципиального зла в подобном запрете, хоть он и не идеален. Пользы вагон. Да, атомной бомбой по воробьям. Но что делать, если из ружья стрелять таки не научились, а воробьёв отстреливать надо?

Date: 2013-03-21 04:49 am (UTC)
From: [identity profile] morfizm.livejournal.com
Воот. То-есть в самом то деле нам надо жестко контролировать отклик интерфейса, причём весьма извилисто подстраиваясь под разные моменты, а не запрещать операции, которые потенциально могут навредить.

Да, это оно.

Profile

ermouth: (Default)
ermouth

November 2021

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 1st, 2026 12:24 pm
Powered by Dreamwidth Studios