Pull to refresh
4
0
Антон Поваров @einstein_man

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

Send message
Не собираюсь.
Комментирую оригинальный посыл статьи, про рождение тредов из initialization list конструктора.

Тема вызова виртуальных функций из конструктора — не связана с «как отстрелить себе ногу с std::thread».
У std::thread есть default constructor.
На мой взгляд более простое решение — просто запустить поток в теле конструктора, там уже все members проинициализированы.
И не забыть, что деструктор std::thread позовет terminate, если не сделать join к нему (или detach).
И unique_ptr тоже не нужен, ибо есть operator=, который сделает move.

Примерно так: onlinegdb.com/By5-qJkuN
#include <thread>
#include <string>
#include <iostream>

struct test_t
{
    test_t()
        : str_{"hello world"}
    {
        t_ = std::thread([this]{
            std::cout << "str = " << str_ << std::endl;
        });
        t_.detach();
    }
    
private:
    std::thread t_;
    std::string str_;
};

int main()
{
    test_t t;
    getchar();

    return 0;
}
Расскажите, за счет чего потенциальный выигрыш «на порядок вверх»?
Ну как всегда это есть комбинация специфических требований (которые проистекают из-за горы уже написанного кода и внедренных систем), усталости от существующих инструментов (т.е. «блин, теперь приходится еще и это поддерживать самим, ибо оно у нас постоянно ломается»), и — не стану скрывать — некоторого желания сделать под себя «как нам надо» (ну not invented here).

Сначала был facebook scribe, который просочился повсюду и захватил умы. Он ломался, мы его слегка патчили, но терпели. Потом fb забросил его (да и код не отличался поддерживаемостью anyway).
После какого-то из раундов борьбы — мы сказали — да ну его, давайте заменим.

Смотрели fluentd — было опасение, что не потянет стриминг (гигабит с тачки например), да и у нас далеко не везде json — надо дофига переделывать. (Могу слегка наврать, было лет 5 назад).

Flume — не хочется ставить jvm на все машины.
rsyslog — олдскульно, юзаем в некоторых задачах, не очень понравился по полу-техническим, полу-субьективным причинам.

Все-таки пожалуй здесь две основных причины
1. Есть уже готовые работающие вещи, которые заточены некоторым образом (в нашем случае — под scribe, текстовые логи, доставку в виде файликов в одном каталоге и т.п.).
2. Есть чемпион, который говорит — чуваки, я счас все запилю классно и так, что этот проект реально будет завершен не через год (3 миллиона строк кода на пхп, 3000+ серверов, 150+ server-side девелоперов). А будет через месяца два. И это происходит как раз, когда мы понимаем — что уже наболело и надо делать.

p.s. мы юзаем на самом деле кучу разных вещей для разного рода «стриминга»: rsyslog тот же, logstash-forwarder был, scribe был. kafka есть.

p.s.2. github.com/badoo/lsd — не самый свежий код, правда.
Насчет protobuf — в чем сложность с ним при отладке?
Если речь про «он же бинарный» — у нас есть простые инструменты превращения бинарки в json. Например — даже конфиги сервисов описываются в .proto, но фактически пишутся/генерируются и хранятся в json (слегка пропатченном, с комментами и tail comma).
Go мы часто используем для задач, которые плохо ложатся на php и хорошо — на Go (concurrency ж киллер фича).
Если при этом же нет жестких требований по контролю памяти или cpu — тогда Go в самый раз.

Например — у нас есть сервис, который шедулит задачи в нашем скриптовом облаке. Сервис (с прекрасным названием LSD) доставки логов между машинами (a-la facebook scribe).

Еще — хороший кейс, имхо, для Go — когда нужна интеграция данных из кучи источников. Например — для распределенного кеша, нужны данные о пользователе, его контактах, последних онлайн действиях и координатах.
Сходить в кучу источников, объединить данные в правильном выходном формате — очень удобно и быстро делается на Go.
Если вы умеете C + Go + PHP — напишите пожалуйста mkevac с рассказом о себе.
> И еще, где всем любопытным можно еще вопросы позадавать помимо как здесь?
задавайте здесь, не стесняйтесь.
— удалено — промахнулся тредиком
ну в данном случае имелись в виду os-level процессы, как средство одним nodejs приложением заюзать много cpu.

насколько я знаком с erlang elixir — тамошние процессы скорее ближе как раз к goroutines, в том смысле, что ими управляет рантайм и каким-то образом их выполняет на os-level threads/processes.
В дополнение к demi_urg

Есть такая штука как cppteam/ateam ideas.
Это просто документ, куда скидываются достаточно слабо структурированные идеи — что можно улучшить и где надо бы допилить.
Крупными мазками там также лежит техдолг, вида «нужно вот эту подсистему в будущем переделать, т.к. нам это понадобится для внедрения фичи X» или «я чувствую, что это заболит через какое-то время».

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

Процедур особых нет, просто стараемся, чтобы работа по техдолгу / текущим «допилам» была где-то в пределах 20-40% времени на разработчика, не больше.
Возможно немного не формат :)
Порекомендуете инструменты / пакеты / подходы к unit-тестированию в Go, чтобы у вас научиться, когда этим плотно займемся?
И насчет полной замены PHP на Go.

В вакууме — это вполне возможно, и насколько я знаю, в некоторых компаниях «Go микросервисы» смотрят во внешний мир, делают бизнес логику и отдают «странички» клиентам.
Был, например, доклад, упоминавший об этом на недавнем Highload.

В случае же Badoo — это не думаю, что нужно (@mkevac об этом тоже писал), работает же хорошо :)
Да и мало реально — миллионы строк уже написаны и работают, крутые и умные коллеги работают, инструменты и тестирование построены. Было бы контрпродуктивно это менять.
Ну мы уже умеем писать single-threaded софт поверх event loop с callback hell :) (хотя, насколько я знаю, с promise и подобными техниками — все уже не так больно).

Киллер фича Go — она ведь в «нормальной» concurrency, встроенной в язык.

В nodejs можно, полагаю, нарожать много процессов и таким образом заюзать все ресурсы железа, но возникает вопрос — а как хранить состояние, которое нужно всем? (например, в одной из наших задач — полтора миллиарда координат пользователей для near-realtime обработки и фильтрации).

Понял. Кластер в одном DC с RF = 2 на данный момент, в разных стойках, вот это все.
Данные, которые сейчас в CTS, едут из двух DC в один, у нас есть «гарантированный» линк между ними (сколько-то сотен мегабит), плюс — естественно — публичный интернет (ну трафик шифрованный, да :) ).

О проблеме линка между DC — что вы имеете в виду?
Насчет opensource: пока не готовы, т.к. чувствуем, что надо бы огрести побольше боли и накопить опыта эксплуатации в разных сценариях. Например у нас в CTS сейчас едут в основном около-продуктовые данные. Хотим построить второй кластер — для технических метрик (времена ответов сервисов/баз/etc, потребление ресурсов, и т.п.). Там будет примерно столько же данных.
Плюс — java мир для нас не совсем пока родной и мы только учимся, например, понимать и тюнить JVM, развиваем/изучаем инструменты.

Clickhouse выглядит интересно, но нас довольно мало и мы пока не готовы быть «early adopters”, хотим подождать пока вырастет community, чтобы потом прильнуть к знанию великого all.
Если данные сравнительно легко изолировать от остальной части системы (грубо — вытащить из базы), то вполне можно попробовать класть это дело в tarantool тот же и написать lua процедур, которые будут управлять этим делом. Все будет персистентно, но «база» и «кеш» в одном месте, так что не надо заботиться о синхронизации.

Минусы понятные — усложнение инфраструктуры, отдельный код (у вас сайт не на lua наверняка? :)) которым надо рулить/ревьюить/выкладывать.

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

Information

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