Entry tags:
Clojure, ленивость и отложенные отчеты
Очередной раз стукнулся об ленивость.
Делаю фоновый расчет отчетов - клиент просит у сервиса "посчитай мне отчет", тот ему возвращает идентификатор-ссылку на future со считалкой отчета и далее клиент опрашивает сервис на предмет "а не готов ли наш отчет" и тот ему отвечает либо "не готов" либо "готов, вот тебе данные".
Ну, склепал очередь отчетов - атом, в нем мап, в мапе идентификаторы запрошенных отчетов и future к ним. Запускаю - а оно мгновенно говорит, "да, вот отчет готов, забирай" и давай его считать и отдавать. В потоке запроса, не в рабочем потоке future.
Ленивость. Оно возвращает башку последовательности данных отчета сразу, "на тэбэ, дорогой, форси меня". И запрос готовых данных (в том числе, даже просто попытка в целях отладки посмотреть на мап с future) - вызывает форсинг последовательности.
PS: И еще обнаружил очередную фичу кложури - thread-local bindings протаскиваются во все вызовы, которые перекладывают работу в другие потоки. Т.е. конкретно тут - я в запросе часть общих параметров (типа имени пользователя) складываю в thread-local binding чтобы не протаскивать их руками через 100500 функций, думал, что при вычислении внутри future придется их доставать и перекладывать во второй поток - а оно уже сделано.
Авторы кложури не перестают удивлять своей крайней адекватностью и практичностью языка.
Делаю фоновый расчет отчетов - клиент просит у сервиса "посчитай мне отчет", тот ему возвращает идентификатор-ссылку на future со считалкой отчета и далее клиент опрашивает сервис на предмет "а не готов ли наш отчет" и тот ему отвечает либо "не готов" либо "готов, вот тебе данные".
Ну, склепал очередь отчетов - атом, в нем мап, в мапе идентификаторы запрошенных отчетов и future к ним. Запускаю - а оно мгновенно говорит, "да, вот отчет готов, забирай" и давай его считать и отдавать. В потоке запроса, не в рабочем потоке future.
Ленивость. Оно возвращает башку последовательности данных отчета сразу, "на тэбэ, дорогой, форси меня". И запрос готовых данных (в том числе, даже просто попытка в целях отладки посмотреть на мап с future) - вызывает форсинг последовательности.
PS: И еще обнаружил очередную фичу кложури - thread-local bindings протаскиваются во все вызовы, которые перекладывают работу в другие потоки. Т.е. конкретно тут - я в запросе часть общих параметров (типа имени пользователя) складываю в thread-local binding чтобы не протаскивать их руками через 100500 функций, думал, что при вычислении внутри future придется их доставать и перекладывать во второй поток - а оно уже сделано.
Авторы кложури не перестают удивлять своей крайней адекватностью и практичностью языка.
no subject
Два селект топа каждый раз, или тянут всё на клиент и перекладывают на грид, или что-то промежуточное, вроде "посчитали конечную табличку, оставили на сервере, по мере листания на клиенте получаем из неё куски"?
no subject
Меня огорчает мысль о том, что этот запрос выполняется повторно на каждую страницу, поэтому теоретически, надо бы выполнить его один раз и закэшировать.
no subject
Кстати, интернет-поисковики как раз перевыполняют запросы каждый раз при листании серпа, кэшировать им получается сложнее. При этом, что интересно, чем дальше листать, тем им технически печальней -- яндекс, например, принципиально дальше сотой страницы не пускает, даже если десять миллионов результатов найдено.
no subject
no subject
no subject
no subject
А для динамических нужны какие-то более другие методы работы, в т.ч. и кэширование результата запроса.
no subject
Пейджинг собственно только для того и нужен, чтобы особо недоверчивые были уверены что они "проверили всё глазками".
no subject
no subject
no subject
no subject
Проблема только с хипстерскими базами, где нет айдишек, но там пейджинг это вообще секс в гамаке стоя :)
no subject
no subject
"Плевать всегда и всем" это чисто красноглазый подход. Поэтому вас к клиенту допускать нельзя на пушечный выстрел, приходят такие, и клиенту заявляют: "вы дураки, вам (никому) не нужно".
no subject
Ты пойди спроси у бизнеса что-нибудь типа такого: вот в этом списке, который секретарша твоя тыкает, может СЛУЧИТЬСЯ НЕКОНСИСТЕНТНОСТЬ!
Он такой: "чо?"
Ну ты такой объясняешь попроще. Типа листаем список на страницу 2, а на странице 1 уже новые данные появились. Что делать? Варианты такие:
- данные на момент открытия показывать ($199 чтобы добавить кнопку рефреш и $1000 на обучение персонала тыкать ее периодически, и покрытие косяков и нервных срывов у тех, кто тыкнуть забыл)
- делать рилтайм-добавление айтемов с клевой анимацией (всего $1599).
- забить болт ($0, ненулевая вероятность что какая-нибудь секретарша раз в год что-то там не найдет)
Как ты думаешь, что выберет бизнес?
Я думаю что только какие-нибудь фейсбуки, на каких-нибудь мега-важных ключевых главных страницах, решают подобные проблемы. Остальные прагматично кладут болт. А те, у кого по этому поводу свербит душа - как раз красноглазые и есть.
no subject
Я годы жизни провёл на встречах, пытаясь клиента уговорить на изменения таких типа мелочей, но не сказав прямо что клиент идиот. Так вот такого типа требования "обеспечить показ всех затребованных данных"
это и есть консистентность, если потом запись со страницы убежит - будет открыт дефект и делать нормально всё равно прийдётся.
Тем более что сделать нормально совсем легко.
no subject
Вопросы:
- сколько ID-шников взяли? Фильтрация, как правило делает скан по базе, элементов может быть много, запрос может быть сложный. Чем больше достаем - тем все сильнее начинает тормозить. TOP ограничивает скан, и мы как минимум первую страницу достаем быстро, а дальше люди ходят редко, сильно реже чем на первую.
- когда сбрасывать этот кэш? Что должно произойти, если мы на 2-й странице нажали F5? Что должно произойти если F5 нажали на первой странице?
- где хранить этот стейт? Сессия - таки не резиновая.
- все хорошо если у нас простая база. Что если у нас, как в этом самом ЖЖ, все кэшами в три слоя покрыто? Ну возьмем мы из второго кеша в третий - актуальности данным это не добавит. Надо делать push-обновления.
Пейджинг и рил-тайм вообще не очень дружат. Посмотри как сделано в том же самом жеже - он вполне может показать запись с предыдущей страницы, если в ленту запись добавилась. Никого это не парит вообще, это понятное поведение. Более того - я лично по этому делу понимаю что на первой странице появилось что почитать.
Вконтактик добавляет записи налету, и у него пейджинга нету. Может быть такой подход и лучше, но это уже неиллюзорно дороже в разработке.
no subject
Вот именно, запрос мы делаем в моём решении только один раз. Вытащить в сложном запросе 20 или 200 айдишек это практически пофиг, а сделать 10 запросов по 20 это тяжелее намного
"- когда сбрасывать этот кэш? Что должно произойти, если мы на 2-й странице нажали F5? Что должно произойти если F5 нажали на первой странице?"
Когда поменял критерии поиска и(или) нажал "искать". Естественно он так на первый лист грида попадает.
"- где хранить этот стейт? Сессия - таки не резиновая."
зависит от языка, архитекруты итп. От курсора до JSON в браузере.
"- все хорошо если у нас простая база. Что если у нас, как в этом самом ЖЖ, все кэшами в три слоя покрыто? Ну возьмем мы из второго кеша в третий - актуальности данным это не добавит. Надо делать push-обновления."
Если я в этой системе работаю, то я знаю кеши и весь ад вокруг, естественно выбираю решение подходящее для этого ада. Если я не знаю как в моей системе работают кеши и как в ней сделать чтобы работало корректно - я иду искать другую работу. Не надо мешать задачи.
no subject
Вот именно в этом отличие теории и практики. Да, если тащить топом - надо будет сканить повторно. Но если посмотреть сколько раз юзеры открывают первую страницы, сколько раз - вторую, сколько раз - третью, то становится ясно что надо оптимизировать только первую.
>Когда поменял критерии поиска и(или) нажал "искать". Естественно он так на первый лист грида попадает.
А если юзер знает что у него айтем появился (новый пост в жж, соседняя секретарша вбила)? Как дать ему понять что вот этим действием он лазит по кешу, а другим - тащит свежие данные?
no subject
ты предлагаешь её "не решать", предложение крутое, но как-то не удовлетворяет клиента. Про выдачу бреда на очередных страницах я уже всё написал.
Пациент понимает что он лазит по "кешу" если он хочет получить обновление - нажимает поиск. Не встречал ни одного юзера, который не понимает что перелистывание на другую страницу не значит перепечатывания книжки наново. Конечно умельцы типа тебя последнее время пытаются сломать мозг юзеру, ломая этот банальный принцип. Потом получается фейсбук, где вообще непонятно что где когда откуда и почему прыгает.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Мой поинт в том, что вместо того чтобы оба варианта с недостатками. А главное - что вместо того, чтобы за это все париться, гораздо полезнее за то же время допилить поиск и фильтрацию.
Потому что листать страницы - реально последняя мера для юзера, после того как не получилось отсечь все нужное поиском и вывести так, чтобы все было перед глазами на одном экране.
no subject
да забудьте про ЖЖшки и вконтактики. В реальных бизнес задачах реального энтерпрайза якобы "реально последняя мера для юзера" это очень частая задача. Приведу пример ещё один, надо мне распечатать отчёт на 20 страниц. Но предварительно проверить не попал ли туда бред случайно. Если я посмотрю только на первую страницу это будет ок? Или мне все 20 страниц одним списком показывать и пусть скроллят?
Я даже хуже скажу, предвижу что с развитием "пальцевых" интерфейсов проблема консистентного пейджинга станет ещё более остро, тот бардак и индусятина которая позволяется сегодня не выдержит проверки временем. ТАкое моё ИМХО.
А сделать догрузку "новых" результатов в конце списка другим цветом (а в процессе перелистывания зажечь звёздочку что появились новые) это тоже легко и просто с моим механизмом.
no subject
no subject
Мне сложно представить ситуацию когда нельзя автоматизировать задачу "просмотреть портянку на 10 страниц, найти то-то и посчитать то-то". В крайнем случае, когда надо универсально и дешево - делается тупо выгрузка в Excel.
no subject