• Как считать счётчики и не сбиться со счёта
    0

    Ну хорошо :) Вы используете очередь. В очереди пересчитываете счётчик полностью, т.к. инкрементное обновление считаете ненадёжным. Благодаря «схлопыванию» удаётся снизить накладные расходы, т.к. «при реактивном изменении счетчика (100500 хомячков в секунду) расчет производится только 1 раз на over 9000 фактических изменений». Я правильно вас понял?

  • Как считать счётчики и не сбиться со счёта
    0

    Откатывать транзакцию или нет — зависит от бизнес-требований. Можем ли мы совершить действие если обновлние сётчика не гарантировано? Можем ли мы позволить себе иметь задержку при рассчёте счётчика? Можем ли мы не менять значение счётчика, если было подряд +1 и -1, или, например нам важно получить рейтинг 100, а потом обратно 99, т.к. при достижении 100 срабатывает триггер и пост становится золотым. Очереди — это замечательно, очень удобно и, во многих случаях незаменимо. Они просто не имеют, ИМХО, прямого отношения к теме топика.

  • Как считать счётчики и не сбиться со счёта
    0

    Логично что отправка письма в фоне с повтором при неудаче, т.к. уведомление тут вторично. Во всех проектах отправка email/sms/push и прочих уведомлений делается так. С утвердительным ответом от платёжной системы наоборот, т.к. оплата важнее. А к чему это вы?

  • Как считать счётчики и не сбиться со счёта
    0

    Рейтинг пользователя на хабе скорее всего да, не вызовет большого перебора, немного ступил. Но одновременно с ним нужно пересчитывать ещё рейтинг хаба. Там будет перебор всех постов хаба. Но мне всё же странно, почему вы наставиваете на полном пересчёте вместо инкрементного обновления, когда оно намного производительнее. Вам не верится что инкрементное обновление может не сбиться? :) Думаете что 1+1+1 в какой-то момент может стать 2 или 4, если повторять эту операцию много раз?

  • Как считать счётчики и не сбиться со счёта
    0

    Если схлопывать несколько обновлений в один, то готов с натяжкой согласиться. Тем не менее, два SELECT SUM() имеет сложность O(N1) + O(N2), где N1 и N2 число постов в старом и новом хабе (это при наличии индексов, при отсутствии это число всех постов на Хабре). Т.е. SQL, каким бы волшебным он не казался, честно пробежится по всем постам хаба и просуммирует рейтинг. Если схлопывания, про который вы писали, нет (а это иногда ограничение бизнес-требований), при большой соц. сети с кучей показателей, то полный пересчёт на производительности скажется драматически.

  • Как считать счётчики и не сбиться со счёта
    0

    Ок. Нам в очередь пришёл id поста и мы посмотрели по changelog-у, или получили сразу в виде параметров помимо post_id следующие поля: old_hub_id, old_is_published, old_is_deleted, old_user_id, и из базы (которая к этому моменту кстати могла опять измениться) или как-то ещё вычислили актуальные на момент срабатывания счётчика hub_id, is_published, is_deleted, user_id. Да, может это звучит необычно, но на dirty реализована передача черновика другому пользователю, по этому предположим что автор тоже может измениться. Какой вы напишите обработчик для обновления вашего «кеша» рейтинга пользователя на хабе?

  • Как считать счётчики и не сбиться со счёта
    0
    Увеличивает доступность сервиса, так как ресурсоемкие вычисления производятся последовательно, а не параллельно.
    Увеличивается отзывчивость интерфейса, так как пользователь не ждет обновления счетчика.

    Ну тут мы кажется сошлись во мнениях, я в комментарии написал то же самое.


    В случае изменения рейтинга/удаления/отправки в черновик в очередь отправится id поста.

    Ну допустим пользователь отредактировал пост сменив хаб и скрыв в черновики. Как мы узнаем что хаб был сменён (а значит нужно вычесть рейтинг поста из рейтинга в старом хабе) и что пост не был в черновиках до этого?


    кешем будет таблице счётчиков [hub_id, user_id] --> rating с сортировкой по убыванию рейтинга.

    Ну если я потом смогу по этому кешу сделать запрос


    SELECT hub_id, rating
    FROM user_hub_rating
    ORDER BY rating DESC
    LIMIT 10

    То у нас просто разное понимание терминологии что считать кешом.

  • Как считать счётчики и не сбиться со счёта
    0

    А чем очередь помогает? Считать в очереди или не нет это вопрос нужен ли вам синхронный счётчик или можно иметь значение с задержкой. В некоторых случаях при отказе в обновлении счётчика нужно откатить транзакцию оменить всё действие. Иногда это вопрос скорости отклика, если на какое-то действие (лайк, к примеру) обновляется слишком много счётчиков и это приведёт к ощутимой для пользователя задержке при синхронном обновлении, то нужно перенести часть рассчётов в очередь.


    Допустим у вас в профиле список хабов, в которые вы внесли максимальный вклад. Это запрос по таблице счётчиков [hub_id, user_id] --> rating с сортировкой по убыванию рейтинга. Рейтинг на хабе это, к примеру, сумма рейтингов опубликованных и неудалённых постов пользователя на хабе. Что вы будете класть в очередь? Как на основе этого будете обновлять счётчик? Чем поможет в этом случае кеш?

  • Как считать счётчики и не сбиться со счёта
    0

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


    Идея ловить тригерами изменения и отправлять на обработку в очередь на той же БД (PGQ) мне, в принципе понравилась. Этот подход позволял отлавливать только изменения, при этом писать логику их обработки на нормальном питоне. Но сама PGQ по сравнению с Celery отвратительна — это раз. Триггеры отлавливающие изменения приходилось обновлять вместе с миграцией БД, короче не слишком приятно выходило. Но потенциал в этом подходе есть.

  • Как считать счётчики и не сбиться со счёта
    0

    А, понятно. Я сначала не понял, что вы про хранение счётчиков только в кеше. Я тут ответил.

  • Как считать счётчики и не сбиться со счёта
    0

    Иногда такой подход оправдан. Но для некоторых вещей просто неприемлем. Например, из Трипстера: запись на экскурсию с ограниченным числом участников. После того, как максимальное число людей оплатило, регистрация на событие закрывается, неоплаченные заказы отменяются, всем участникам и гиду приходят уведомления.


    Второй вариант — значения счётчиков вам постоянно нужны для выборок.

  • Как считать счётчики и не сбиться со счёта
    0

    Да, я имел в виду именно это. И да, дело, по большей части, в дороговизне полного пересчёта на каждое изменение. Никакое кеширование, тут помочь не может — что именно вы будете кешировать? :)

  • Как считать счётчики и не сбиться со счёта
    0

    А понял, спасибо

  • Как считать счётчики и не сбиться со счёта
    0

    Не, не могу помочь. На Хабре я давно не работаю

  • Как считать счётчики и не сбиться со счёта
    0

    У нас тоже финансовые операции присутствуют, и, некоторые напрямую зависят от счётчиков. По этому когда я пришёл на проект и обнаружил MyISAM, первым делом бросился переводить на InnoDB и заворачивать в транзакции. Но к тому моменту накопилось столько мусорного кода, что банально не найдены и необеззаражены все места где что-то типа


    order = Order.objects.get(pk=order_id)
    order.status = Order.STATUS_PENDING_PAYMENT
    order.save()

    Т.е. без транзакций и SELECT FOR UPDATE, без, хотя бы save(update_fields=['status']) и прочее. И, конечно, это ломает счётчики.


    А кто у вас добавляет в очередь пометку о необходимости обновить счётчик?

  • Как считать счётчики и не сбиться со счёта
    +1

    Ну так я же старался проще :) Подскажите что кажется сложным. Я надеялся, что самым понятным будет код, кроме которого можно особо ничего и не читать

  • Как считать счётчики и не сбиться со счёта
    0

    Хм… Не до конца понял. В одном из проектов я тоже делал возможность пересчёта одного или нескольких счётчиков. Счётчики задаются декларативными правилами типа:


    class Experience(models.Model):
        review_count = models.PositiveSmallIntegerField(u"Число отзывов", default=0, db_index=True)
        review_rated_count = models.PositiveSmallIntegerField(u"Число отзывов с оценками", default=0)
        review_rating_sum = models.FloatField(u"Сумма оценок", default=0)
    
        class Counters(Counters):
            review_count = Counter('Review.experience', lambda review: review.published)
    
            review_rated_count = Counter(
                'Review.experience', 
                lambda review: review.published and bool(review.rate)
            )
    
            review_rating_sum = Counter(
                'Review.experience',
                lambda review: review.rate if review.published and review.rate is not None else 0
            )
    
    class Review(models.Model):
            experience = models.ForeignKey(Experience, related_name='reviews')

    Т.е. тут тоже обычные счётчики даже не в отдельной таблице, а прямо в основных моделях.


    В вашем случае increment( counterName, ±1) вызывается вручную в методах публикации/распубликации или это происходит автоматически на основе конфигурации? Как примерно устроена конфигурация? Как работает пересчёт?

  • Как считать счётчики и не сбиться со счёта
    +2

    А расскажете? Как было, что было проще? И да, какие из моих рассуждений показались вам заумными, может я переформулирую? :)

  • Как считать счётчики и не сбиться со счёта
    +4

    На картинке счётчик постов, если приглядеться :)

  • Emotiv Insight — нейроинтерфейс за 229$
    +1
    Со сроками они конечно облажались, я уже почти было перестал надеяться, но вчера, наконец-то коробка поступила на склад LiteMF, и через 1-2 недели должна быть у меня :) Правда обошлось в 3 раза дороже (включая пересылку LiteFM $60, выяснилось что эта фигня может быть доставлена только USPS Express Mail).
  • Не учите фреймворки, учите архитектуру
    +1
    Спасибо, т.е. можно было бы сказать «Highland для коммуникаций M и V через контроллер», да? Я так и подумал сначала.

    Мне подход FRP очень понравился. В какой-то момент разных событий и промисов становится так много, что напрашивался какой-то новый подход.
  • Не учите фреймворки, учите архитектуру
    0
    А почему Highland только для коммуникации M и V? Где C? Просто у меня сложилась привычка связывать M и V через контроллер, и, чтобы они друг о друге не знали. У V иногда может быть своя M для внутренних состояний, он так же может быть слегка сам себе контроллер. Пример: блок с необязательными полями, который можно свернуть/развернуть. Тут есть Модель данных, которая мапится на поля ввода, и микромодель Вида с одним атрибутом скрыто/развёрнуто. V сообщает C об изменении полей, C может отправить изменения в M. Изменения M тоже слушает контроллер, и может при этом обновить V. А у вас как обычно устроено?

    P.S. Спасибо за библиотеки, отличная подборка!
  • Pixi-editor — простая рисовалка на pixi.js
    +1
    Кстати, хорошая идея для мильтитач-инструмента: рисование линии с толщиной зависящей от расстояния между пальцами :) Особенно на больших экранах было бы круто
  • Установка и интеграция solr с django под Ubuntu 12.04
    0
    О! Может вы мне ответите на этот вопрос о готовке ядер Solr-а? toster.ru/q/101767

    С момента публикации вопроса ни одного ответа. Но за это время мне посоветовали перейти на ElasticSearch у которого конфиги на yaml/json, бинарник не требующий jre и другие плюшки.
  • Новая навигация и другие изменения на Хабре
    0
    И отредактировать комментарий не могу. Для тач устройств не подходит вешать события только на onclick для многих элементов. Самое простое и по-быстрому — делать $el.on(«click singleTap», ...), или touchStart
  • Новая навигация и другие изменения на Хабре
    0
    Красиво, просторно, но пока глючно. Не могу с айфона минусовать комментарии. И поюсовать тоже.
  • «Левада»: только 5% граждан РФ считают недопустимым ограничение информации в интернете. Наш альтернативный опрос
    0
    Москва, 31, 3 вопроса
  • Обычная (или не совсем обычная) транслитерация на Python
    +1
    А вы смотрели unidecode? У меня правда был другой критерий отбора, чтобы переводила в транслит любой набор символов на любом языке.
  • Об организации кода в django-приложениях или толстые модели – это прекрасно
    +1
    Года два назад меня посетила мысль, что в Django явно не хватает ещё одного слоя — «бизнес-логики». Сейчас понимаю, что вопрос гораздо глубже… Те кто пишет про всякие SOLID, DDD и пр. явно правее тех, кто выбирает между толстой моделью, толстым менеджером, толстым view, толстой формой или отдельным logic.py :)

    Забавно, что к пониманию многих вещей меня подтолкнуло погружение в JavaScript, и, конкретно вот эта статья на Хбре. Знаю, в среде питонистов часто бытует религиозная ненависть к яваскрипту — абстрагируйтесь, почитайте, статья больше о понимании принципов чем о языке.
  • Шпаргалка по шаблонам проектирования
    0
    А ещё, не секрет, по ним строится колонка «похожие публикации», которую многие смотрят
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    0
    Вот тут можно посмотреть на js:
    sociation.org/static/js/sociation/compare.js
    Там основная функция принимает как аргумент функцию сравнения. Они идут ниже. Чем ниже тем новее и лучше :) Самый простой и эффективный пока — последний comporator11.
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    0
    Тогда проще на абсолютных числах:
    — 500 и 1000 упоминаний (разность — 500, в 2 раза популярнее)
    — 100500 и 101000 (разность 500, отношение 1.0049, т.е. «почти одинаково»)

    Насчёт 1 и 2 — чем меньше частота, тем больше погрешность. Но нас же низкочастотные слова вообще не очень интересуют?

    Если вечером будете экспериментировать, скину позже несколько формул
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    +1
    Ну да, такое маленькое хобби :)
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    0
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    0
    Если сортировать по разнице, то в одном списке будут слова характерные только для 1-го или только для 2-го ресурса, и не характерные для обоих одновременно. И то, разница в данном случае — это неверно. Нам ведь важно во сколько раз слово популярнее, а не на сколько (например 20%-10% = 10%, 100%-90% = 10%, при этом в первом случае популярность выше в 2 раза, а во втором в 1.111...).

    Я когда рассуждал, придумал такую простую визуализацию. 2 оси, по одной — популярность слова в первом списке, по второй — во втором. Пусть они нормированы [0:1], тогда слова около «точки» 1,1 — это максимально популярные общие для 2-х ресурсов слова, 1,0 — характерные для 1-го, и 0,1 для второго ресурса. Вроде всё просто, нужно только правильно поделить плоскость на 3 группы (например популярные слова Хабра, Лепры и обоих одновременно). Остаётся вопрос — как именно это сделать наиболее правильным образом :)
  • И снова закинул старик невод… (парсинг хабра, продолжение)
    +1
    А как вы решили задачу: есть 2 списка чего-то по популярности, нужно найти самое популярное из списка 1 при этом не популярное в списке 2 (и наоборот, соответственно)?

    Я просто несколько раз сталкивался с подобной задачей в общем виде (например сравнение ассоциаций к двум словам на Sociation), находил несколько удовлетворяющих меня решений, но все они какие-то «нестопудовые» и мало математически обоснованы.

    Или вы просто взяли какой-то порог, типа меньше 5-и употреблений, значит его нет?
  • Почему QA всё ещё не Stackoverflow?
    –3
    Ради справедливости хочу заметить, что на StackOverflow довольно высокий порог входа. Там очень мощная репутацационно-кармическая система, гораздо мощнее чем у Хабра. Так что, насчёт уменьшения барьера я с вами не соглашусь.

    Хорошая идея с релевантными вопросами в сайдбаре, единственная проблема — большая конкуренция на этот блок. Чего там уже только нет.

    Ещё и QA, на мой взгляд, не очень удобный дизайн собранный из элементов обычной публикации.
  • Нужна ли кастомизация для bootstrap?
    +1
    Неплохое начинание, спасибо!

    Подброшу вам в копилку идей. В бутстрапе всего 7 основных цветов, всё остальное — их вариации. Ну, ещё вероятно опция тёмный на светлом / светлый на тёмном для фона. Было бы здорово плясать от цветовой схемы (собственной, или с того же kuler и подобных). Тема перекрашивает весь бутстрап, а дальше уже можно кастомизировать отдельные элементы.

    Из тех сервисов что я видел выделяются 2 полярных типа: либо почти полная кастомизация, либо готовые стили. Мне видится полезным именно какой-то промежуточный вариант. Несколько настроек меняющие весь стиль (например основные цвета, ч/б фон, шрифт, размер шрифта маленький/большой/средний, радиус скругления уголков), а дальше более глубокая кастомизация, если требуется.
  • Bootstrap-wysiwyg: крошечный текстовый редактор
    0
    Неплохо. Из замеченных недостатков:

    • На iOS приходится тыкать по кнопкам дважды (нужно обрабатывать тач события, самое простое on «click touchstart»)
    • При клике на link хотелось бы иметь возможность редактировать существующую ссылку, если на ней стоит выделение
  • Генерация случайных лиц в PaperJS
    –1
    Блин, как злят подобные новости без реального примера и кода :(