cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
90 stars 0 forks source link

Редизайн Networking TS #268

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +22, -0 Автор идеи: dreverser

Из того что я смотрел предлагаемый в стандарт Networking TS это практически тот же самый asio из boost'a

Вот только в бусте он asio(асинхронный IO и для сериала, девайса, сети) а предлагаемый в стандарт он почему то весь превращается в Networking

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

Очень кратко по тому что я вижу из последнего Networking TS http://en.cppreference.com/w/cpp/experimental

1)

вытянуть из пространства net/ и втянуть в стандарт отдельным независимым пропозлом, это всего лишь байтстримовый поток. В который можно писать в конец, и читать сначала. Помоему не хватает только метода avalible() который скажет длинну от прочитанного до записаного (аналог из QT). Убрать из него все зависимости на реактор если они есть. Должна быть возможность использовать как независимую от реактора сущность. Асинхронка если она сильно прибита к нужно переместить в один из файлов реактора(io_context). 2) вытянуть из пространства net/ и втянуть в стандарт отдельным независимым пропозлом. Это асинхронный IO, он имеет отношение не только к нетворкингу, но и к IO девайсов. В него же добавиться возможность работать асинхронно с дескрипторами через . Все зависимости на сокеты если они есть должны быть убранны из реактора. 3) убирается жесткая зависимость на реактор (io_context) в конструкторе. А вся асинхронка переходит в отдельную сущность к примеру async_socket либо как то оборачивается в шаблон. остаются в пространстве net.
apolukhin commented 3 years ago

Виктор Губин, 27 марта 2018, 18:14 ИМХО asio вообще не стоит стандартизировать в том виде в котором она есть.

Недостатки:

Очень сложный API

Пространства имен в 4-ре уровня, скажем boost::asio::ip::tcp к тому-же не бывает непонятно в конце цепочки пространство имен или имя типа.

experimental::net::v1::ip::std - как этим вообще пользоватся ?

Множество служебных классов

например открытие клиентского сокета:

    boost::asio::io_context io_context;
    boost::asio::ip::tcp::resolver resolver(io_context);
    boost::asio::ip::tcp::resolver::results_type endponints = resolver.resolve("localhost", "http");
    boost::asio::ip::tcp::socket socket(io_context);
    boost::asio::connect(socket, endpoints);

Тоже в С:

  struct addrinfo hints = {AF_UNSPEC,SOCK_STREAM};
  struct addrinfo *res;
  getaddrinfo("localhost","80", &hints, &res);
  int s = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
  connect(s,res->ai_addr,res->ai_addrlen);  

Тоже в Java:

Socket socket = new Socket("localhost", 80);
InputStream is = socket.getInputStream();

И ничего не мешает сделать 2-х строковый вариант в объектно-ориентированном С++

Строковые константы типа "http" - зачем ?

Отдельные сущьности для ip_v4 и ip_v6

  asio::tcp::endpoint endpoint(asio::tcp::v4(), "localhost" ));

  asio::tcp::endpoint endpoint(asio::tcp::v6(), "localhost" ));

От объектно-ориентированной билиотеки подобного рода вещей не ждешь.

Современная сетьевая библиотека без поддержки защищенных соединений (SSL/TLS) выглядит странно.

yndx-antoshkka, 27 марта 2018, 19:30 Напишу письмо авторам Networking TS, послушаем что они скажут по вашим замечаниями.

Andrey Davydov, 27 марта 2018, 23:37 Пункт 2, как я понимаю, автоматически следует из Executors TS, а Networking TS зависит от и будет переделан под Executors TS.

yndx-antoshkka, 29 марта 2018, 10:49 Поговорил с авторами.

Пункты 1 и 2 будут решены во время слияния TS в стандарт. Я предложил убрать namespace net:: в принципе, чтобы буферы, таймеры, база для соектов и прочие вещи оказались в namespace std, а всё что связано с сетью - в namespace std::ip. Возражений не последовало. Свзяей между буфером и асинхронностью нет.

По поводу пункта 3. Есть подозрение, что не нравится не столько связь сокетов с io_context, сколько то что в текущей имплементации конструктор io_context достаточно тяжёлый, с динамическими аллокациями и т.п. Автор предлагает продемонстрировать возможность создания zero overhead имплементации io_context. Интересно? Или нужно именно оторвать сокеты от io_context?

dreverser, 29 марта 2018, 12:45 Обновлено 29 марта 2018, 11:06

Мне asio тоже не нравится, в большей степени из за его тяжелой имплементации.

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

И я надеюсь что стандарт оговаривает интерфейс а не имплементацию.

И каждый отдельный компилятор напишет свои имплементации и имплементация asio не войдет во все компиляторы.

Вот от части из за таких сложностей АПИ многие и пишут свои велосипеды.

Пункт два уже разбили. Конкурент группа забрала екзекуторы в отдельный пропозл.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0443r5.html

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0761r2.pdf

В networking TS мне не нравится что это обсуждается в целом одним пучком. Но если они дали добро на разбиение на части в финальной коммите то хорошо.

Буферы связаны с ректором через асинхронные операции.

"17 Buffer-oriented streams"

Я не смотрел имплементацию. Но не понятно эти streams шаблонные и никак не прибитые к буферам или там какой то интерфейс и он прибит к реактору ?

И где объявлены эти самые буферы. В файле буфера или где то в отдельном файле ?

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

По сокетам аналогично. Если как я понял буферы не прибиты к реактору. А асинхронка на шаблонах, То почему так же не сделать и с сокетами ?

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

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

Хочет кто то юзать прибитыми к конструктору сокеты. Ну ок, пусть в стандарт введут async_socket унаследованый от сокета, где в конструкторе будет реактор.

Хотя у меня тут же вопрос. А почему тогда не сделать async_buffer ? Ну или опять же, не плодить async_socket а сделать шаблоны асинхронки как это сделано для буфера.

dreverser, 29 марта 2018, 12:49 Может вместо "Buffer oriented streams" сделать "async oriented streams" ? которые смогут работать и для буферов и для сокетов. Тогда надобность в реакторе для конструктора сокета отпадает. И сокет становится таким же легким как и буфер.

dreverser, 29 марта 2018, 12:53 Про отцепили екзекуторс вот ссылка

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0958r0.html

yndx-antoshkka, 31 марта 2018, 19:48 Поискал embedded устройства с сетью, на которых нет асинхнонной работы с соединениями. Не нашёл. Нашёл лишь примеры embedded устройств на которых сетевое взаимодействие выполняется очень похоже на Networking TS.

Никаких упоминаний реактора, проактора и прочих деталей реализации в io_context (и в Networking TS) не нашел. Проблем с внедрением на embedded не вижу.

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

Набросал интерфейс где async классы не обладает синхронными методами. Пострадал use case, кодга после асинхронной операции мы синхронно забираем данные из сокета, зная что данные в сокете уже есть (классический реактор). Итог: стало сильно хуже.

В связи со всем выше перечисленными вопрос: для чего вы хотите пункт 3) и как именно предлагаете его реализовывать?

dreverser, 1 апреля 2018, 12:44 В контекте моих мыслей реактор = io_context и все что у него под капотом

asio сам по себе является реактором в большинстве имплементаций и проактором только для iocp виндового.

На мой взгляд asio усложнена изза ее интрузивности сокета и таймера.

Основная мыль была не в том что бы дать отдельно блочный и асинхронный сокет. А в том что бы дать простую сущность типа socket в которой только пару полей - хендл и ошибка. и методы send/receive/sendAddress/receiveAddress/open/close/итд

А уже потом этот socket заюзать во внутренностях asio.

Зачем это и что это даст. Велосипеды все равно будут писаться. Примеров я видел достаточно. Один из тот же scraps из битторента. Так почему тем что хочет работать с "простым" сокетом не дать наконецто стандартный интерфейс ? Что бы они наконец то ушли от прямого сетевого апи ?

В asio я нашел socket_holder. Но он к сожалению ничего кроме закрыть хендл - не умеет. Я бы как минимум добавил в него все возможные методы send/receive/sendAddress/receiveAddress/open/close/итд унивицировал все socket_ops::*

А сам socket_ops:: в большей части(особенно там где он использует хендл), перевел на обновленный socket_holder. Сам socket_ops:: тоже сильно переусложнен, но сложные части тянуть в socket_holder не стоит.

Сам socket_holder вытянул в стандарт. Пусть люди пользуются. Хватит уже этих апи.

Касательно самой архитектуры asio, я в размышлениях, зачем такая интрузивность.

Все это можно было хранить и в реакторе, а после регистрации в реакторе отдавать ссылку на туже самую структуру. Сейчас очень странно видеть как async_result::get отдает void

dreverser, 1 апреля 2018, 19:36 Есть еще некоторые пожелания насчет имплементации ендпоинт адресов v4 v6

По моим наблюдениям за свой многолетний опыт. Трансформация IP+PORT происходит только около сетевых айпи. В остальном коде это не требуется.

Так зачем в address_v4/v6 пихать платформо зависимый тип ?

Почему бы не вставить туда обычный набор типов IP+PORT

и для трансформации в sockaddr_in/6 создать пару функций address2sock/sock2address ?

Это полностью избавит от функций network_to_host_short/host_to_network_short network_to_host_long/host_to_network_long в endpoint.

И я почти уверен что данные 2 функции больше чем в socket_holder имлементации для преобразования данных к апи вызовов использоваться не будут.

marakew commented 2 years ago

опять заглохло

значит принять корутины без имплементации в библиотеке можно было

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

мне кажется в комитете кто то занимается саботажем

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

marakew commented 2 years ago

вкратце удалось нагуглить такое

https://isocpp.org/files/papers/P2464R0.html A P0443 executor is not an executor. It's a work-submitter. https://wg21.link/p0443r9

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

это пять

теперь чуваки вкалывают над https://wg21.link/p2300r3 но кого то все равно что то не устраивает и вот что конкретно не устраивает, пока не нахожу есть инсайд инфа ?

marakew commented 2 years ago

полистав P2300, это очередной опус facepalm чуваки пытаются скрестить threadpool+future+promise, накрутить сверху пейплайн как это любит ерик ниeблер и назвать это правильными экзекуторами а по факту кто то хочет пролоббировать libunifex в стандарт

marakew commented 2 years ago

земля слухами полнится пишут что пропозл sender/receiver для экзекуторов - dead

надеюсь теперь придут к принятым везде модели channels и не будут заниматься ерундой