Search
Write a publication
Pull to refresh

Comments 35

если вы захотите написать телеграм бота, то вы (были) вынуждены делать это на python. Библиотеки на других языках непопулярны и зачастую не выполняют даже минимальных требований

Простой бот легко пишется без всяких библиотек и питонов, да вот хотя бы на perl )

Но на С конечно быстрее.

Раньше хабр был весь в статьях-нативках телеграм каналов, а теперь телеграм библиотек. Прогресс?

Зря вы так на vcpkg. Версионность там есть, хотя немного нетривиально реализуется. Свои библиотеки подключать - тоже без проблем. И у меня такое чувство что вы путаете репозиторий с проектами который управляется Майкрософтом, и саму систему vcpkg.

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

Пока ваше дерево зависимостей имеет глубину 1-2, пока используемые библиотеки ведут себя нормально, все работает. Дальше CPM начинает испытывать трудности и они сами предлагают использовать vcpkg в таком случае.
В какой-то момент поймал себя на мысли, что мне проще написать рецепт для vcpkg, чем в очередной раз разбираться с тем, как для какой-то библиотеки собрать зависимости и как ей потом подсунуть флаги компиляции - vcpkg решает это за меня, причем кроссплатформенно.

Какие трудности у cpm возникнут ?

Попробуйте, например, VTK добавить через CPM. Ну или CPython. А ещё лучше VTK с поддержкой python.
Я не говорю, что это невозможно, в конце концов принцип работы у всех одинаковый. Просто в случае с vcpkg это кто-то уже сделал и оно тестируется, а в случае с CPM это придётся делать самостоятельно.

Это вопрос хорошего cmake у библиотеки. Я вообще считаю, что лучше не использовать кривые библиотеки, пусть постараются и сделают хотя бы 1 нормально написанный файл в проекте (CMakeLists.txt), иначе их никто не будет использовать

VTK пилит Kitware, так что вряд ли у них плохой CMake. Он не плохой, он объёмный и там много фич с кучей зависимостей, которые в случае с CPM придется разруливать вам.

Насчёт Conan не понял, чем он так плох? Вполне рабочая штука. Хотя да, они сломали всё при переходе на версию 2.0. Но в целом они спрятали зоопарк разных систем сборок библиотек за одним фасадом. Собственные пакеты создаются элементарно.

И я и мои знакомые, которые пытались пользоваться conan зачастую не могут написать рецепт к простейшей библиотеке. А эти люди вообще-то С++ смогли выучить. Это говорит о том, что conan слишком неудобен для реальности

А у меня, вот, получается. И с C++ я знаком, и рецепты на конане пишу.

Конан очень удобен для случаев, когда надо собрать чей-то чужой уже готовый проект. Добавление одного файла conanfile (.py или . txt) позволяет установить все зависимости без изменения исходников самого проекта. CPM так не может.

не сказал бы что прям элементарно, но уж всяко лучше чем устанавливать в систему непонятно что не понятно откуда. Так что я уж лучше разберусь со сложностями conan но буду иметь полный контроль над сборкой зависимостей.

Ещё добавлю про систему сборки:

Вы (действительно!) уверены, что при наличии уже установленного OpenSSL версии 3 будет правильным (и безопасным!) скачивать в исходниках версию 1 с репозитория некого Джанбара из Франции, собирать её из исходников, и (подозреваю) установить её в систему как одну из версий криптобиблиотек?

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

Возможно, это сомнительный путь. Не находите?

-

Ответ на "Почему версия 1": Потому что в файле deps.cmake указан тэг 1.1.1w-20231130. Хотя, возможно, для Джанбара это самая новая версия библиотеки.

Почему версия 1? Даже через буст и шифры в коде явно отключается возможность установить соединение по версии 1 и 2

С OpenSSL вообще непросто, у них есть версия SSL, версия библиотеки и версия TLS, 1.1.1w-20231130 поддерживает TLS 1.2/TLS 1.3.
Это не прям последняя версия, но с ней всё нормально

За старания, конечно, лайк.

если вы захотите написать телеграм бота, то вы (были) вынуждены делать это на python. Библиотеки на других языках непопулярны и зачастую не выполняют даже минимальных требований

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

много библиотек на блокирующих вызовах или с другими фундаментальными проблемами, даже на питоне кажется всего 2 библиотеки, которые стоят рассмотрения (telegram-bot и aiogram)

на блокирующих вызовах

Скорее всего мои боты пока не дошли до того, что это является проблемой (да и вряд ли дойдут).

Сам пишу ботов на Java с использованием TelegramBots и проблем у меня с библиотекой примерно никаких. Всё апи поддерживается, если чего-то мне не хватает, то это косяк апи телеграма, а не библиотеки.

В общем, интересно узнать, что за требования такие к библиотекам.

Абсолютно согласен. Перечислены некие внутренние технические требования, но не внешние к боту, и ощущение, что требования просто высосаны из пальца. И из текста непонятно, таких библиотек нет вообще или нет только для С++.

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

Есть ещё боты с http1, которые заново создают соединение каждый раз при походе в апи, добавляя по 0.5-1 секунде к задержке ответа, это очень ощущается со стороны пользователя

А вот вы про

> оно не зависло навсегда и не тормозило при наличии хотя бы 2 юзеров

А есть какое-то сравнение с питоновскими либами? Или тут в принципе бенчмаркать бессмысленно так-как очень быстро упремся в скорострельность серверов телеграмма?

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

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

Скажите, а чем не устраивает классический вариант когда из главного потока синхронно в цикле полим и запускаем синхронную джобу на пуле потоков которая занимается обработкой?

Насчёт хттп2, чем вас курла не устроила?

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

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

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

Все до этого существующие библиотеки телеграм ботов на С++ требовали установить зависимости вручную.

Имхо только так и надо. Вот например у нас используется йокто, а тамошние художники решили, что ходить в сеть во время сборки это вредно для здоровья. И все эти ваши фетч контенты с сипиэмами не работают, надо костыли делать. Опять же в экосистеме раста этот вопрос решен красиво, библиотека бьётся на более мелкие, т.е. например есть только та что генерит ц++ апи который про жисоны ни сном ни духом не знает, а просто отдает пэйлоад строкой , поверх уже сериализация в структуры и роутинг на команды, где то ещё будет подсос зависимостей из сипиэма в виде отдельной либы. А на границах интерфейсы. Зачем? Ну у нас и культя в проекте тоже есть и у нее тоже на любой вопрос свое решение и жисоны и сеть асинхронная имеются. В идеале я бы мог взять например ваш генератор апи и подставить свой транспорт потом распарсить жисон своей либой уже в свои структуры. Да это все сильно сложнее чем то что у вас, но зато намного проще комбится с существующими проектами. Ваша библиотека для написания бота отдельным приложением с ноля, а в существующий проект так просто как хочется не воткнется.

Корутины конечно модно и все такое, но ведь курла такая же асинхронная (как и культя), а если есть (а иначе нафига этот бот нужен) тяжёлая обработка то без пула потоков с джобами все равно не обойтись. Т.е. ваш демо/эхо бот точно также можно сделать с курлой в один поток, а что не демо так нужен пул все равно, так и зачем тогда эти корутины конкретно в этой либе? Я могу понять выбор корутин как достаточно универсальный интерфейс для транспорта, но вы транспорт гвоздями прибили и заменить его нельзя, тогда зачем корутины?

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

Скажите, а чем не устраивает классический вариант когда из главного потока синхронно в цикле полим и запускаем синхронную джобу на пуле потоков которая занимается обработкой?

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

Плюс если у вас есть какой то тредпул встроенный в библиотеку и по сути глобальный, то это уже фреймворк, такие "умные" библиотеки потом при интеграции с другими ещё более умными порождают 10 тредпулов в одном приложении

Насчёт хттп2, чем вас курла не устроила?

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

И та же асинхронность в курле прикручена как будто сбоку и библиотека кажется не рассчитана на такое использование

На буст у многих аллергия 

страх буста во многом основан на мифах. в TGBM буст используется точечно, например boost asio, т.е. после сборки одного или нескольких .cpp где на asio зависимость, дальше сборка даже трогать буст не будет. Боязнь такой зависимости в основном связана с тем, что люди не хотят мучиться с её подключением. Но CPM решает эту проблему и подключая TGBM вы можете вообще не знать, что там есть буст. И скачивания тоже CPM избегает, если вам это нужно. И если ваш проект уже подключает буст, то CPM возьмёт его из кеша

вы можете генерить жисон, а потом из него генерить с++ структуры. 

не понял тут. По документации генерируется .cpp, потом шаблоны в С++ коде по структурам делают парсинг/сериализацию в json. Какой-то невероятной завязки на json нет, через трейты можно даже добавить поддержку своего json, сейчас там ест поддержка для boost json и rapid json

В идеале вам вообще не нужна билд зависимость от жисон библиотеки

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

 библиотека бьётся на более мелкие, т.е. например есть только та что генерит ц++ 

у нас библиотека итак разбита на множество частей. Отдельно

  • скрипты генерации апи

  • всё связанное с json

  • отдельно связанное с сетью и http1.1 / http2.0

  • отдельно корутины: kelcoro

  • отдельно часть http2.0 для кодирования хедеров по rfc: HPACK

 В идеале я бы мог взять например ваш генератор апи и подставить свой транспорт потом распарсить жисон своей либой уже в свои структуры

никто вам не мешает это делать, можно отправить запрос не парся json и парсить самому. Генератор тоже отдельно существует

Я могу понять выбор корутин как достаточно универсальный интерфейс для транспорта, но вы транспорт гвоздями прибили и заменить его нельзя, тогда зачем корутины?

корутины здесь потому, что это единственный и лучший способ организации асинхронного кода. Насчёт транспорта я не понял, что прибили? Вы хотели по grpc ходить в телеграм? Телеграм позволяет обращаться только по http (и слава богу, ведь grpc та ещё хрень)

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

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

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

Какие задачи решает курл я вроде бы как знаю, и меня удивило, что по вашему мнению он не покрывает хттп2 транспорт. Расскажите какие задачи решает ваша хттп2 реализация которые не решаются курлой? Какой такой гибкости вам не хватает?

И скачивания тоже CPM избегает, если вам это нужно. И если ваш проект уже подключает буст, то CPM возьмёт его из кеша

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

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

Я не очень понимаю, что вы хотите этим сказать. Вы же не утверждаете, что до с++ 20 на этом языке невозможно было реализовать асинхронность? Понятие лучший тоже никак не раскрыто, а если вы на самом деле считаете, что корутины это единственный способ, то качественная оценка лучший не имеет смысла. Это как первый элемент в очереди из одного элемента он же и последний - худший.

Насчёт транспорта я не понял, что прибили? Вы хотели по grpc ходить в телеграм?

Я хочу заменить вашу хттп2 + азию на курлу или культю не меняя код апи.

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

Если вы про SAX парсер то например nlohmann::json умеет такое.

не понял тут

Там сложно объяснить простым комментом поэтому я не буду вдаваться в подробности. Есть ещё одна альтернатива вашей архитектуре, можно парсить хтмл от телеги и генерить какой нибудь стандартный рест апи файл, а уже потом используя стандартные генераторы реста получить готовую либу не только на с++, но и для других языков. Мы например так генерим с++ транспорт культевый для своих рестов, где то мне попадались генераторы и на другие реализации сети. Очевидно эта работа (по предоставлению стандартного реста) должна быть сделана самой телегой, но раз они не сделали то это было бы наиболее полезно.

у нас библиотека итак разбита на множество частей.

Есть разница между разбивкой библиотеки на части/фичи и отделение каждой части в независимую библиотеку. Разбивка на библиотеки сложнее, но как вы говорите гибче. Когда у вас разбивка идёт на фичи, то сборка/зависимости управляются единообразно в родной либе, а когда разбивка на либы, то необходимо предоставить интерфейсы к зависимостям на уровне сборки в каждой либо - больше работы/сложнее, но позволяет легче интегрировать только необходимые части в существующие проекты.

Вы же не утверждаете, что до с++ 20 на этом языке невозможно было реализовать асинхронность?

future, then, калбеки, всё это не способны выражения асинхронного кода, а устаревшее легаси. Никто не выберет футуры и then, когда есть корутины. И корутины прекрасно работают поверх калбеков. В итоге, весь выбор который у вас есть для асинхронного кода это стекфул или стеклес корутины.

Я выбрал использовать стеклес корутины по множеству причин, одна из которых написанная мной библиотека kelcoro, остальное лучше узнавать в докладах, статьях и комитете стандартизации С++, который решил именно этот способ закрепить в стандарте языка

Если вы про SAX парсер то например nlohmann::json умеет такое.

Нет, я не просто про sax парсинг, а sax парсинг потоковый, когда за раз можно предоставить не весь json. nlohhman известен тем насколько он медленный, при этом он проигрывает в удобстве boost json из-за странных дизайн решений, таких как неявная конвертация json во что угодно. Мы серьёзно подходили к вопросу выбора библиотеки для json и есть целая папка бенчмарков различных способов. Ради интереса можете посмотреть на итоговое решение

можно парсить хтмл от телеги и генерить какой нибудь стандартный рест апи файл

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

То есть, я правильно понимаю, что все существующие нормальные боты написаны без использования открытых библиотек или таких ботов нет вообще?

на питоне есть библиотеки, которые выполняют требования из статьи, на С++ - раньше не было

Тогда зачем выбирать С++? Непонятно.

У С++ есть много преимуществ относительно питона - удобнее писать большие и среднего размера проекты, не нужно учить питон и нанимать других программистов, производительность в конце концов. Я бы сказал так, а зачем выбирать питон? Если на С++ бот пишется даже легче?

чтобы оно не зависло навсегда и не тормозило при наличии хотя бы 2 юзеров

добавляя по 0.5-1 секунде к задержке ответа

Это откровенная неправда. Сам знаком с людьми, которые пишут довольно популярных ботов и на JS, и на .NET, и на JVM. Поэтому претензия к блокирующим вызовам выглядит скорее вкусовщиной.

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

Вкратце - нет, неправда: кроме либ на питоне есть и на других яп и довольно развитые поделки, например для go : https://github.com/gotd/td

Там довольно крутая идея использована : чем просто писать либу к апи и потом заниматься всю жизнь её поддержкой,
лучше 1 раз написать парсер TL и сделать либу автогенерируемой (навроде того как имея описание http Rest API на ямле в формате openapi swagger можно генерировать либки)

Для конкретно telegram BOT api нет TL, оно для клиентов телеграма. А TGBM собственно автогенерирует по апи код, но пользователю библиотеки даётся не скрипт генерации, а уже готовый код

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

Эээм, нет?

В ktgbotapi для Kotlin, telegraf для TypeScript, node-telegram-bot-api для JavaScript никаких "задержек по 0.5-1с" нет.

Более того, даже в боте, написанного без фреймворков и с простым поллингом в infinite loop HTTP хэндла getUpdates на Rust, имплементированного с помощью Tokio и reqwest, таких задержек не было.

Как указал Homyakin, это скорее вкусовщина автора, а не что-то реально имеющее место быть.

Sign up to leave a comment.

Articles