Технологии доступности в Linux

Скоро, надеюсь, выложу обзорный материал по архитектуре компонентов обеспечения доступности в российских дистрибутивах. Все активисты по доступности упорно творят в пиратской парадигме, а делать что-то нужно. Привожу здесь текущие основные идеи. Извиняюсь, если без стеснения по техническому перегрузу. По мере развития выложу также ту часть кода, которую решил держать открытой.
Напомню, что AT-SPI — текущая платформа обеспечения доступности в Linux — имеет два принципиальных ограничения: привязка к D-Bus для межпроцессного взаимодействия и отсутствие возможности гибко расширять интерфейсы для описания пользовательских объектов. GTK+ и QT содержат интеграцию с D-Bus, в которую передают информацию об интерфейсе приложений. D-Bus не подходит для высоконагруженного обмена данными: пересылка уведомлений о подключение флешек — нормально, но не описания интерфейсов в реальном времени.
Раз мы пытаемся решить задачу системно, в новый продукт вольём весь необходимый функционал: снятие информации о приложениях, её сбор в едином месте, управление речевыми синтезаторами и пр. Да-да, функциональность VoiceMan проще всего передать сюда.
Нам требуется:
1. Обмен сообщениями, разбитыми на несколько шин: UI, команды синтезаторам и пр.
2. Сборщик интерфейсов (UI), встраиваемый прежде всего в QT, ибо GTK+ в отечественных системах поддержки не находит.
3. Скриптовой инструмент, позволяющий управлять чтением тех или иных компонентов.
4. Инспектор текущего состояния и конфигуратор для пользовательских настроек.
Поскольку мы можем завести шину для передачи команд синтезаторам речи, отдельный речевой сервер нам больше не нужен. Порядок чтения отдельных фрагментов проще передать в компонент скриптования, который с большой вероятностью сделаем на языке Lua.
Инструмент, передающий данные между всеми операторами этой системы, — главный камень преткновения. В строгом смысле он должен поддерживать механизм шин и подписчиков, позволяя предельно быстро им обмениваться данными. Архитектурно это крайне непростая задача, и я немало времени потратил на поиски правильной технологии. Варианты такие:
1. Очереди сообщений Linux. Поддерживают передачу точка-точка и лимитированы по количеству ядром. Одно сообщение надо в цикле рассылать всем подписчикам в их выделенные очереди. Не очень, но зато поддерживают приоритеты сообщений.
2. Разделяемая память. Прекрасная история, но требует синхронизации процессов для доступа к ней, что в результате породит механизм, не сильно проще очередей сообщений. Помимо этого разделяемая память позволит хранить только «свежие» сообщения, и «медленные» подписчики будут терять данные.
3. Именованные трубы (FIFO). Тоже поддерживают передачу точка-точка и не поддерживают, очевидно, приоритеты.
Именованные трубы (как и трубы вообще) для своей работы используют буфер в ядре (с настраиваемым пользователем размером). Другими словами, это по сути разновидность разделяемой памяти, доступ к которой синхронизирует ядро. Но в случае использования труб остаётся задача тиражирования сообщений между подписчиками на шине.
Трубы можно попробовать, но писать весь код синхронизации вручную трудновато. Есть риск эту работу начать и никогда не закончить. И тут весьма кстати Яндекс обновил свою платформу для разработки асинхронных микросервисов userver. Она не совсем для этого, но если критически подумать, вполне подходит для того, чтобы нашу задачу на ней реализовать, и это становится уже весьма реалистичным и оправданным по трудозатратам. Как только сделаю прототип, который покажет, что userver точно подошёл, выкладываю код и лонгрид по теме. Userver позволит в этот проект принести некоторые дополнительные фишки, которых не было ни в AT-SPI, ни в Windows.
Проект будет открытым, кроме плагина для QT.

Начать дискуссию