Pull to refresh
62
0
Виктор Пряжников @bikutoru

Пользователь

Send message

Способ написания кода, при котором сначала пишется код, проверяющий работоспособность нового функционала, а уже после этого реализуется сам новый функционал

с помощью Centrifugo работает красивейший дашборд на ресепшн в московском офисе Badoo

Не только московском, но и лондонском. Спасибо за работу над Центрифугой!

Значит, как минимум два пользователя очень довольны их продуктом)

Что-то подобное есть в дополнительных материалах, которые я приводил:


Репозиторий на GitHub с описанием и тестами разных способов

Там в директории samples/ есть log-файлы с результатами теста разных способов (правда никакой визуализации нет и не очень удобно сравнивать способы друг с другом).

Я такой не видел.


Достаточно просто найти реализацию согласованного хеширования (оно есть, например, в расширении memcached), а вот всё остальное в виде отдельной библиотеки мне не попадалось...

По описанию это очень похоже на вероятностные методы, только вместо случайного числа тут тут время обращения

Честно говоря, вариант с мастер-процессом не выглядит проще в реализации, чем фоновое обновление (хотя сложно "лечить по фотографии").


Если у вас есть много вычислений, которые можно разбить на отдельные части, то их можно обновлять по частям, используя для каждой части вероятностные обновления до истечения времени жизни основного кэша. В этом случае можно и избежать фонового процесса и иметь часть готовых результатов на момент "протухания" кэша итогового результата.

Да, писать в 10 кэширующих серверов долго и дорого, но мы используем это крайне редко. Обычно мы пишем ключ и читаем его только из одного сервера.


Я нашёл меньше 20 групп ключей, использующих схему со всеми серверами. Обычно это какие-то счётчики или кэши конфигурации по странам/городам, которые обновляются только фоновыми скриптами (т.е. мы исключаем параллельные обновления). В онлайне эти ключи только читаются и не отличаются от остальных.


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

Спасибо за замечание, добавил еще один вариант названия

Не так важно, какие именно слоты переносятся между серверами, главное добиться правильного соотношения между количеством слотов у работающих серверов (если веса равные, то и количество слотов на каждом должно быть примерно равно друг другу).


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


Если веса у серверов различны, то отношение количества слотов на этих серверах должно примерно соответствовать соотношению их весов.

В принципе это похоже на то, что делаем мы. Разница только в том, что создание пользователя в начале теста и удаление в конце мы делаем неявно — оно происходит "само" и по мере необходимости. У нас есть пул тестовых пользователей, каждый из которых может быть взят любым тестом. За счет этого:


  • нам не нужно тратить время на создание пользователя и его чистку в момент прогона тестов => тесты работают быстрее
  • мы экономим место на дисках: законодательства некоторых стран требуют хранить данные даже удаленных пользователей, поэтому штатно удаление пользователя не означает DELETE записей о нём из базы. У нас несколько тысяч тестов и мы часто их запускаем, поэтому база бы очень быстро росла (особенно это критично на площадках разработчиков, которые используют общие базы)

После использования пользователя тестом его нужно будет очистить. Это произойдет не сразу, а через какое-то время, когда станет понятно, что "чистых" пользователей осталось мало.


Еще одно отличие, которое я заметил — вы работаете с локальным объектом (например в вызове user.getCandies()). Мы так не делаем потому, что это не даёт возможность запускать тесты на удалённых площадках.


Периодически у нас возникает проблема, что тест проходит на площадке разработчика, изменения мержатся в ветку билда, выкладываются на стейджинг (на котором используются боевые базы данных и сервисы) и там тест начинает падать, хотя на девел окружении проходит. В такой ситуации разработчик может сделать checkout ветки билда на своей площадке (в девел окружении) и запускать свой тест в стейджинг окружении (через отправку серверных команд поверх http). При этом можно менять сам тест, добавлять какие-то дебаги, дополнительные вызовы QaApi, которые покажут, что происходит на сервере.


P.S. Не совсем понял: вы говорите, что у вас по сети ничего не отправляется, но это выглядит как отправка http-запроса


        api().post('/api/v1/buy') // POST запрос на URL покупки
            .set('authtoken', user.getToken()) // задаем заголовки авторизации
            .send(payload) // отправляем запрос

Существующие средства (конкретно Cucumber) используют QA-инженеры, занимающиеся тестированием самих приложений. Тесты, про которые я рассказал, пишут сами разработчики. Нам удобно писать такие тесты на php, т.к. мы получаем за счет этого несколько плюсов:


  • использование уже имеющихся в коде констант (в приведённом коде есть несколько примеров). Благодаря этому мы можем использовать в тесте семантические значения и нам не нужно делать какой-то маппинг;
  • использование привычного разработчикам инструмента — работать с phpunit умеют чуть ли не все разработчики. За счёт этого снижается порог входа для нового человека;
  • ускорение прогона тестов: при использовании phpunit и локальной площадки разработчика тесты работают в рамках одного процесса без http-запросов. Это важно, ведь таких тестов очень много и они не очень быстрые.
Нет, assertGiftAddSuccess — это обычный метод класса теста, который делает серию проверок другими assert-методами. Вот его код:
    private function assertGiftAddSuccess($response, $fail_message)
    {
        $this->assertInternalType('array', $response, "{$fail_message}: an array expected");
        $this->assertArrayHasKey('gift_id', $response, "{$fail_message}: gift id expected!");
    }


У нас есть целая пачка подобных asssertSomething, которые мы используем для упрощения самих тестовых методов.

Magic method здесь — это вызов серверной команды ($ClientGiftSender->ServerGetUser), который собирает из аргументов запрос, отправляет его серверу и разбирает полученный ответ. Тут «магию» мы убирать не пробовали, но думаю, что теряем на ней мы сравнительно немного — ведь в тесте мы работаем с реальной базой и реальными сервисами.
Вот всё, что есть в паблике: https://github.com/tony2001/leptonica, но это очень старая версия.
Как вариант я хотел использовать специальный разделитель в лексемах (например, __EOL__), который бы переводчики добавляли в места возможного разбиения тексов на «сложных» языках. При генерации бейджа код бы либо “выкусывал” его (в случае когда текст помещается в одну строку), либо вставлял на его месте перенос строки. Это бы потребовало ручной работы, но совсем немного, ведь используется всего два-три десятка лексем.

Из очевидных «граблей» — опечатки у переводчиков при вводе спецсимволов, но их можно ловить автоматически: в лексемах с опечатками после разбиения на строки будут символы из двух классов: иероглифов и латиницы, чего в корректных лексемах быть не должно.
Мы выводим тексты на японском слева направо, так что с этой точки зрения особенностей нет. Проблемы там скорее с разбиением на строки — нет классических пробелов и нельзя разбивать на произвольном месте, чтобы случайно не порвать слово, состоящее из нескольких символов. У меня было пару мыслей на этот счёт, но на практике их реализовывать не пришлось — у нас тексты на японском достаточно короткие и в итоге переводчики просто укоротили 1-2 лексемы, которые не помещались в одну строку.
К сожалению, я пока не могу прогнать ваш тест — под рукой нет сервера, где одновременно были бы и leptonica, и gmagick.

В момент поиска графической библиотеки тесты показывали, что leptonica быстрее даже не в 2 раза, а процентов на 25. Было это давно и я не смог найти ни исходников тестов, ни их точных результатов, поэтому сделал новый тест просто чтобы показать (а заодно и самому понять), на каких конкретно операциях leptonica работает быстрее. Я думаю, что тут tony2001 сможет сказать больше меня.
Вам правильно ответили — мы используем сессии не в файлах, а в памяти. Технически они доступны на серверах, где происходит генерация изображений, но только если запрос послал пользователь. У ботов нет доступа к данным из этой сессии, поэтому нельзя на неё полагаться и нужно передавать все необходимые параметры в URL бейджа.

Арабский еще очень тяжело отлаживать — его почти никто не знает и после внесения правок непонятно, правильно они работают или нет. Приходилось после любого изменения готовить примеры картинок, отправлять их переводчикам и ждать от них обратной связи :-)
Я сделал еще один вариант теста, в котором используется ваш вариант. resizeImage() работает где-то на 5% быстрее scaleImage(), но в рамках всего теста разница будет не очень заметна.
Вот дополненная версия теста и его результаты: https://github.com/pryazhnikov/php-image-processing-tests/tree/im_resize_vs_scale
UPDATE `banners` SET `id`=1, `name`='test', `info`='long-long description', `hits`=3560, `iduser`='2', `created_at`='2012-02-17 13:14:02', ... WHERE `banners`.`id`=1
Как я понял из этого запроса, есть таблица с баннерами, в которой хранится информация о баннере (название, какое-то описание, дата создания) + общее число хитов этого баннера.

Мне было бы интересно вынесение поля hits из этой таблицы, т.е. создание отдельной таблицы banners_hits (banner_id, hits), в которой хранятся те же самые данные, но отдельно от всех остальных данных по баннерам. Логика такая: данные по хитам (скорее всего) нужны не всегда и обновляются гораздо чаще, чем остальные данные, поэтому может иметь смысл хранить их отдельно в сравнительно небольшой табличке.

В общем это только мои предположения и мне хотелось знать, не пробовали ли вы что-то подобное.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity