Да, я с вами полностью согласен, что здесь скорее бенчмарк в вакууме, чем тест реальной производительности. НО, я подчеркну, что бенчмарк все-таки хоть что-то должен показывать. Когда он показывает ~3 мс для 10, 100, 1000 вызовов функции, стоит задуматься, нужен ли такой бенчмарк. А когда он показывает 3 мс, 30 мс и 300 мс (если линейная асимптотика), то с этим уже проще работать, так как можно по flamegraph искать горячие точки и делать оптимизации константы или даже асимптотики.
Все-таки на маленьких значениях не видно разницы, т.к. в результатах не видно кратного увеличения времени при кратном увеличении количества сообщений. Если добавить побольше вариантов (10k, 100k, 1kk, 10kk), то вырисовывается другая картина:
Это не критика библиотеки, скорее замечение к тому, что бенчмарк не показательный получился, т.к. значения по большей степени константные получились. А уже на таких результатах можно по flamegraph найти горячие места и пооптимизировать.
Спасибо за статью! У меня появилось желание изучить тему акторов поподробнее, выглядит интересно.
Посмотрел результаты и код бенчмарка. Подозреваю, что бенчмарки все-таки протестировали время инициализации runtime (tokio vs actix). Выглядит так, что 10, 100, 1000 сообщений не достаточно для того, чтобы увидеть заметный результат.
Можете попробовать, вдруг получится. У меня в приоритете - добавить недостающие базовые функции, улучшить архитектуру, повысить надежность и качество приложения.
Не будет работать в фоне. Архитектурно отличия скорее нет, оно есть только в деталях реализации. У меня не получилось с Jami или Tox из-за нестабильности звонков и самого приложения.
Чтобы peer узнал о другом peer, нужен третий участник (в данной статье это ntied-server). Serverless не получится, я даже не знаю, возможно ли здесь достичь serverless, при отсутствии статического белого IP хотя бы у одного участника.
Если участник не в сети, то сообщение попадает в очередь и потом когда-нибудь, когда оба участника в сети, будет доставлено. Здесь нет сервера для таких случаев, я не решал пока такую проблему.
Ничего плохого сказать не хочу. Из моего опыта - нестабильная работа (креши) и проблемы со звонками (неявные разрывы). При неправильном использовании интерфейса - переход в такое состояние, из которого можно выйти только перезапуском приложения. Функция "поделиться экраном" сделана довольно оригинально - через видеозвонки и переопределение в настройках устройства камеры на область экрана. Правда, помимо оригинальности, смотреть демонстрацию было довольно проблематично. Вполне возможно, что за два месяца проблемы исправили, или же проблемы были именно у меня, а не в приложении.
сможешь ли ты сделать лучше не полагаясь целиком и полностью на свой маленький релей сервер
Да, в моем случае уже получилось лучше, чем Jami, в плане работоспособности. Если говорить про OpenDHT, то интеграция возможна, но это задача низкого приоритета, поскольку мой текущий подход уже решает основные проблемы.
Стоит ли заморачиваться с п2п
Стоит, ведь P2P подразумевает прямое соединение между собеседниками (в случаях когда это возможно), которое ограничено только пропускной способностью канала собеседников, а не сервера.
Нигде в статье не указывается, что месенджер анонимный. Анонимность и нормально работающие звонки (в идеале с видеосигналом) - крайне нетривиальная задача.
Есть две проблемы, почему здесь не используется только message_id (который генерируются UUIDv7):
В распределенной системе нет гарантии, что у обоих участников часы синхронизированы.
Сообщение может быть составлено и отправлено на устройстве пользователя в момент плохого соединения или вообще, отсутствия соединения с собеседником. В результате сообщение может быть доставлено со значительной задержкой.
log_id позволяет сериализовать запись каждого сообщения не зависимо от времени, гарантируя что у каждого собеседника история является append-only.
А вы им пользовались? Перед тем как что-то колхозить, были попытки подружиться в том числе и с Jami. К сожалению, с простыми звонками ничего не вышло: у меня и у собеседника были те же проблемы - постоянно надо дергать аудио, чтобы нужное устройство ввода/вывода использовалось, прерывания звонков. Для моих целей Jami как и Tox, не подошел на тот момент.
Когда реализовывал транспорт я смотрел на спецификацию quic чтобы почерпнуть немного идей. Однако руки еще не дошли изучить как обстоят дела с реализацией quic для rust и насколько его реалистично адаптировать к p2p.
Использовалась библиотека sea, но возникли проблемы с линковкой зависимостей под windows. Сейчас там 2 кодека - raw и ADPCM, реализацию можно найти в репозитории.
Я рассматривал libp2p, но на момент рассмотрения у меня не было глубоких знаний (проверенных на практике) и хотелось получить минимальный рабочий вариант без сложных зависимостей, с максимальным контролем и пониманием происходящих процессов. В текущей реализации есть один изьян - соединения не работают при включенном VPN (возможно у меня такой попался, но это вроде распространенный случай). Сейчас планирую добавить TURN, это должно покрыть все возможные случаи, а дальше уже понять, что нужно ли переходить на libp2p (библиотека очень обширная).
Насчет создания нужного чата - нужно знать публичный ключ собеседника (точнее хеш от ключа). Дальше собеседник решит принять от вас запрос или нет. Тут да, как в tox или jami. Метаинформация о контактах нигде, кроме как между собеседниками не хранится, и искать другими способами не получится.
Плюсы в больших проектах не сильно быстрее на этапе компиляции. По моим ощущениям даже медленнее (возможно из-за отсутствия модулей, большого числа сложных шаблонов или еще чего-то). А дебаг, почему не компилируется огромный плюсовый проект крайне "приятный".
О каких уникальных фичах идет речь? Поиск по ключу, вставка, удаление, итерирование есть в обычном map[K]V. Упорядочивание по компаратору в каком-нибуть BTree, RBTree или AVLTree есть.
Можно сказать, что это своего рода гибрид между списком и деревом, только без всяких заморочек.
Хотелось бы конкретики. Открыл код, по сравнению с листом - код выглядит сложнее. По сравнению с деревьями поиска +- одинаково, может чуть проще.
Как итог:
Никакого описания принципа работы.
Отсутствие оценки скорости работы "уникальных операций" (хотя бы асимптотическая оценка).
Отсутствие примеров, когда данная структура может дать преимущество над общеизвестными бинарными деревьями поиска и хеш-таблицами.
Да, я с вами полностью согласен, что здесь скорее бенчмарк в вакууме, чем тест реальной производительности. НО, я подчеркну, что бенчмарк все-таки хоть что-то должен показывать. Когда он показывает ~3 мс для 10, 100, 1000 вызовов функции, стоит задуматься, нужен ли такой бенчмарк. А когда он показывает 3 мс, 30 мс и 300 мс (если линейная асимптотика), то с этим уже проще работать, так как можно по flamegraph искать горячие точки и делать оптимизации константы или даже асимптотики.
Все-таки на маленьких значениях не видно разницы, т.к. в результатах не видно кратного увеличения времени при кратном увеличении количества сообщений. Если добавить побольше вариантов (10k, 100k, 1kk, 10kk), то вырисовывается другая картина:
Это не критика библиотеки, скорее замечение к тому, что бенчмарк не показательный получился, т.к. значения по большей степени константные получились. А уже на таких результатах можно по flamegraph найти горячие места и пооптимизировать.
Спасибо за статью! У меня появилось желание изучить тему акторов поподробнее, выглядит интересно.
Посмотрел результаты и код бенчмарка. Подозреваю, что бенчмарки все-таки протестировали время инициализации runtime (tokio vs actix). Выглядит так, что 10, 100, 1000 сообщений не достаточно для того, чтобы увидеть заметный результат.
Можете попробовать, вдруг получится. У меня в приоритете - добавить недостающие базовые функции, улучшить архитектуру, повысить надежность и качество приложения.
Не будет работать в фоне. Архитектурно отличия скорее нет, оно есть только в деталях реализации. У меня не получилось с Jami или Tox из-за нестабильности звонков и самого приложения.
Чтобы peer узнал о другом peer, нужен третий участник (в данной статье это ntied-server). Serverless не получится, я даже не знаю, возможно ли здесь достичь serverless, при отсутствии статического белого IP хотя бы у одного участника.
Если участник не в сети, то сообщение попадает в очередь и потом когда-нибудь, когда оба участника в сети, будет доставлено. Здесь нет сервера для таких случаев, я не решал пока такую проблему.
Ничего плохого сказать не хочу. Из моего опыта - нестабильная работа (креши) и проблемы со звонками (неявные разрывы). При неправильном использовании интерфейса - переход в такое состояние, из которого можно выйти только перезапуском приложения. Функция "поделиться экраном" сделана довольно оригинально - через видеозвонки и переопределение в настройках устройства камеры на область экрана. Правда, помимо оригинальности, смотреть демонстрацию было довольно проблематично. Вполне возможно, что за два месяца проблемы исправили, или же проблемы были именно у меня, а не в приложении.
Да, в моем случае уже получилось лучше, чем Jami, в плане работоспособности. Если говорить про OpenDHT, то интеграция возможна, но это задача низкого приоритета, поскольку мой текущий подход уже решает основные проблемы.
Стоит, ведь P2P подразумевает прямое соединение между собеседниками (в случаях когда это возможно), которое ограничено только пропускной способностью канала собеседников, а не сервера.
Нигде в статье не указывается, что месенджер анонимный. Анонимность и нормально работающие звонки (в идеале с видеосигналом) - крайне нетривиальная задача.
Есть две проблемы, почему здесь не используется только message_id (который генерируются UUIDv7):
В распределенной системе нет гарантии, что у обоих участников часы синхронизированы.
Сообщение может быть составлено и отправлено на устройстве пользователя в момент плохого соединения или вообще, отсутствия соединения с собеседником. В результате сообщение может быть доставлено со значительной задержкой.
log_id позволяет сериализовать запись каждого сообщения не зависимо от времени, гарантируя что у каждого собеседника история является append-only.
Запустить приложение можно так:
cargo run --bin ntiedЗа лицензирование отдельное спасибо, обязательно разберусь.
А вы им пользовались? Перед тем как что-то колхозить, были попытки подружиться в том числе и с Jami. К сожалению, с простыми звонками ничего не вышло: у меня и у собеседника были те же проблемы - постоянно надо дергать аудио, чтобы нужное устройство ввода/вывода использовалось, прерывания звонков. Для моих целей Jami как и Tox, не подошел на тот момент.
Когда реализовывал транспорт я смотрел на спецификацию quic чтобы почерпнуть немного идей. Однако руки еще не дошли изучить как обстоят дела с реализацией quic для rust и насколько его реалистично адаптировать к p2p.
Использовалась библиотека sea, но возникли проблемы с линковкой зависимостей под windows. Сейчас там 2 кодека - raw и ADPCM, реализацию можно найти в репозитории.
Я рассматривал libp2p, но на момент рассмотрения у меня не было глубоких знаний (проверенных на практике) и хотелось получить минимальный рабочий вариант без сложных зависимостей, с максимальным контролем и пониманием происходящих процессов. В текущей реализации есть один изьян - соединения не работают при включенном VPN (возможно у меня такой попался, но это вроде распространенный случай). Сейчас планирую добавить TURN, это должно покрыть все возможные случаи, а дальше уже понять, что нужно ли переходить на libp2p (библиотека очень обширная).
Насчет создания нужного чата - нужно знать публичный ключ собеседника (точнее хеш от ключа). Дальше собеседник решит принять от вас запрос или нет. Тут да, как в tox или jami. Метаинформация о контактах нигде, кроме как между собеседниками не хранится, и искать другими способами не получится.
В принципе, а почему бы и сейчас не открыть. Точно не фейк, можно проверить
Плюсы в больших проектах не сильно быстрее на этапе компиляции. По моим ощущениям даже медленнее (возможно из-за отсутствия модулей, большого числа сложных шаблонов или еще чего-то). А дебаг, почему не компилируется огромный плюсовый проект крайне "приятный".
О каких уникальных фичах идет речь? Поиск по ключу, вставка, удаление, итерирование есть в обычном map[K]V. Упорядочивание по компаратору в каком-нибуть BTree, RBTree или AVLTree есть.
Хотелось бы конкретики. Открыл код, по сравнению с листом - код выглядит сложнее. По сравнению с деревьями поиска +- одинаково, может чуть проще.
Как итог:
Никакого описания принципа работы.
Отсутствие оценки скорости работы "уникальных операций" (хотя бы асимптотическая оценка).
Отсутствие примеров, когда данная структура может дать преимущество над общеизвестными бинарными деревьями поиска и хеш-таблицами.
Пост об утилите на 10 простых строчек, да и еще с ошибками в одном предложении ("простую версия"). Зачем, для кого, почему...
Нужно считать по байтам:
2(порт источника)+2(порт назначения)+4(номер последовательности)+4(номер подтверждения)+1(длина заголовка и часть резерва).