Try   HackMD

Tarantool Network Framework API

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

Для чего это предполагается использовать?

  • Интеграция HTTP-фреймворка H2O, когда воркеры H2O работают в отдельных тредах, крутят свой событийный цикл, терминируют TLS, обрабатывают HTTP-запросы, а в TX передаётся уже полностью разобранный запрос, на который он должен ответить.
  • Реализация протокола Redis для прозрачной замены Redis
  • Перенос сетевой части реализации memcached из tx в отдельный тред

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

Разработчик создаёт модуль, который реализует необходимые ему функции. В функциях, работающих в tx-треде можно пользоваться методами работы с базой и файберами (в т.ч. yield'ить). Нельзя блокироваться. Нельзя запускать "свой" событийный цикл. В функциях, работающих в тредах, нельзя работать с базой, файберами, основным событийным циклом.

  • Загрузка (mod = require 'h2o')
    • Должна быть выполнима до вызова box.cfg()
    • Выполянется из TX треда.
    • dlopen + проверка наличия нужных символов
    • Создаёт lua-модуль и возвращает его
  • Конфигурация и запуск. (mod.cfg{ ... })
    • Желательна возможность вызова до box.cfg()
    • Вызывается из lua
    • Принимает lua-таблицу с параметрами и передаёт на уровень C
    • Проверяет все параметры и выбрасывает исключение в случае некорректности
    • Инициализирует слушающие сокеты.
    • Инициализирует и запускает необходимое количество рабочих тредов
    • В рабочем треде запускается полезная нагрузка, реализующая listen/accept цикл
  • Переконфигурация (mod.cfg{ ... } повторно)
    • Вызывается из lua
    • Принимает lua-таблицу с параметрами и передаёт на уровень C
    • Проверяет все параметры и выбрасывает исключение в случае некорректности
    • Инициализирует новые параметры. Должны поддерживаться:
      • Смена сокета
      • Изменение кол-ва рабочих тредов
    • Cтарые треды и их соединения должны завершаются gracefully, т.е. по завершению запроса. (На совести разрабочика модуля)
      • Необходимо API для выставления треду признака работать/завершать-работу и сигнальный интерфейс
  • Общение между тредами
    • При обработке соединений и запросов может быть необходимо отправить сообщение и данные из рабочего треда в tx тред. Для этого нужен API вызов, который позволит передать данные, обратный контекст и вызовет функцию модуля в tx треде.
    • Вызванная в tx треде функция может взаимодействовать с box api, вызывать fiber_yield и т.п. и в конце концов должна иметь возможность передавать данные и контекст обратно.
    • Нужно учесть, что в рамках одной пользовательской сессии возможен многократный обмен сообщениями (напр. в сценариях WebSocket, HTTP/2, HTTP/3), т.е. простая пара call/return не подойдёт
    • Т.о. необходим механизм двунаправленной асинхронной передачи сообщения вместе с вызовом функции.
  • Насколько мне удалось разобраться в iproto.cc, всё уже есть и это называется cbus, cpipe и cmsg
    • Нужно вытащить в виде публичного интерфейса для модулей cbus, cpipe и, возможно, rlist