Rust MPSC хочется странного?


#1

Продолжается реализация генератора кода обработчика протокола BlackBox для Rust.
В целом процесс приема и отправки пакета выглядит так.
Отдельный thread принимает и парсит входящие бинарные данные и готовые пакеты укладывает в кольцевой буфер,
Другой thread выгребает пакеты из этого кольцевого буфера и занимается диспетчеризацией полученных пакетов в зарегистрированные обработчики
Если же нужно отправить пакет, для этого нужно положить отправляемый пакет в другой кольцевой буфер, за пополнением которого следит третий Thread.

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

В поиске реализации подобного на Rust, я допустил ошибку. Убил много времени на поиск и моделирования того как сделать кольцевой буфер на Rust. Так чтобы он был многопоточным…

Пока однажды не понял, что в Rust все уже готово … в виде MPSC Channels.
И ни каких кольцевых буферов не нужно.
Просто нужно уметь вырваться из аквариума С… и радикально пересмотреть происходящее.

Это все хорошо. Но осталась проблема регистрации обработчиков событий.

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

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

И я уже было начал искать способ реализации такого вектора… но! остановился.

Ведь уже вместо кольцевого буфера входящих пакетов у меня будет MPSC Channel … так что на принимающей стороне этого канала будет крутиться поток диспетчеризации…

А что если схитрить и … поскольку Channel Multi-Producer то вместо пакетов в канал попытаться отправлять… собственно обработчик событий + команду что с ним сделать, удалить, добавить и проч…

Поток диспетчеризации при получении такого объекта будет читать его тип Пакет это ли обработчик с командой и соответственно реагировать.
Если пакет - то дипетчеризировать
Если обработчик с командой выполнять действия с обработчиком согласно команде.

Вопрос - не слишком ли это м-м-м… радикально?


#2

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


#3

этот подход называется

Пусть даже и так… и хотя по-прежнему “пугает” радикальность задуманного…
сейчас пересматриваю текущую реализацию на С, C# и JAVA…

и вижу в обсуждаемом новом варианте одни плюсы

сейчас, для реализации массивов однотипных обработчиков событий:
на С# - использована встроенная, стандартная модель событий/ делегатов
на JAVA - ConcurrentLinkedQueue

и на каждом из наборов обработчиков висит свой затратный Lock…
который приходится захватывать при перечислении и при добавлении/удалении обработчиков.

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


#4

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


#5

извиняюсь намека на понял… в SCALA, AKKA использовать приходилось.

actix - это хорошо, взял на заметку… однако.
в BlackBox на Rust хотелось бы:

  • сохранить возможность работать на микроконтроллерах, пусть даже и не на 8 битных как на С …
  • встроив только тонкий слой диспетчера событий, не навязывая, оставить за пользователем выбор масштабности системы последующей обработки пакетов…