RasEcosystem
Это несколько приложений для администрирования кластеров 1С:Предприятия. Я начал разрабатывать их как альтернативу штатной консоли.
Изначально никакой «экосистемы» я делать не собирался. Мне хотелось получить примерно ту же консоль, только без нескольких вещей, которые постоянно мешают при работе:
- необходимости держать и переключать несколько версий штатной Windows-консоли при работе с серверами разных версий платформы;
- отсутствия нормального поиска;
- древовидной навигации, которая при большом количестве кластеров и информационных баз начинает скорее мешать;
- довольно медленной работы самого интерфейса.
Сначала я собирался исправить всё это в одном экспериментальном проекте. По крайней мере, так задача выглядела в начале.
Готовые сторонние инструменты для администрирования уже есть — например, ПУСК. Но мне хотелось сделать собственный open-source вариант и развивать его под свои сценарии. Отсюда отдельный API, локальная копия состояния инфраструктуры и возможность писать независимые клиенты.

Первый тупик — как вообще говорить с RAS
Я довольно быстро упёрся не в интерфейс и даже не в поиск. Сначала нужно было понять, как новое приложение вообще будет взаимодействовать с сервером администрирования 1С.
Для удалённого администрирования кластера в составе платформы есть сервер администрирования RAS и консольная утилита rac. Утилита rac подключается к RAS, выполняет команды администрирования и выводит результат в консоль.
У RAS всё же есть официальные программные интерфейсы — для Java и встроенного языка 1С. Но готового API для .NET нет. В моём случае прямой доступ означал бы отдельный Java-сервис или ещё одну прослойку между приложением и RAS.
Поэтому я решил начать с rac.
Сам подход выглядел криво: запускать CLI из приложения и строить поверх него свой интерфейс. С другой стороны, rac — штатная часть платформы с достаточно понятной моделью работы: аргументы командной строки, код возврата, stdout и stderr. Для первого эксперимента такой компромисс показался мне приемлемым.
Так появился RasGate.
RasGate
RasGate я решил оставить тонким шлюзом между приложением и rac. Gate разворачивается как отдельный сервис, а в его конфигурации указывается исполняемый файл rac. К конкретному RAS сам Gate не привязан.
Gate получает по HTTP готовый список аргументов, запускает rac, контролирует выполнение процесса и возвращает код завершения, stdout и stderr. Аргументы, включая адрес RAS, формирует вызывающая сторона. Поэтому один Gate технически может работать с несколькими доступными ему RAS.

При этом сам RasGate практически ничего не знает о предметной области. Он не должен понимать, что такое кластер, информационная база или сеанс с точки зрения RasEcosystem. Его задача находится уровнем ниже: превратить работу с локальным CLI в сетевой интерфейс.
Сам компонент из-за этого получается небольшим, но каждый запрос фактически означает запуск отдельного процесса rac. Gate должен следить за этими процессами, корректно завершать зависшие вызовы, не оставлять после себя мусор и не превращать машину, на которой он запущен, в кладбище процессов rac.
Почему поверх Gate понадобился ещё один слой
После появления Gate казалось, что основная проблема решена. К RAS теперь можно обращаться по сети. Остаётся подключить клиент к Gate, научить его формировать аргументы rac и наконец заняться нормальным интерфейсом.
Но тогда вся проблема с версиями платформы переезжала в клиент. Команды rac, их параметры и получаемые данные могут отличаться между версиями 1С. При прямой работе с Gate разбираться в этих отличиях пришлось бы каждому клиенту.
А кроме этого ему понадобится:
- параллельно работать с несколькими Gate;
- собирать и объединять полученные данные;
- учитывать различия между версиями
rac; - приводить результаты разных версий к единой модели.
И это только получение данных. Дальше понадобятся сеансы, управление базами и другие административные операции. Если оставить всё это в клиенте, он очень быстро превращается в комбайн.
Тащить всю эту сложность в каждый клиент мне не хотелось. Работу с несколькими Gate и совместимость версий я вынес в отдельный компонент — RasHub.
RasHub
Так RasHub и стал слоем между Gate и клиентами. Он знает о нескольких Gate, определяет доступную через каждый из них версию rac, формирует подходящие аргументы и приводит ответы к общей модели. Клиент выбирает зарегистрированный Gate и отправляет прикладной запрос в терминах кластеров, информационных баз и других сущностей, а не готовую команду CLI.
Потом всплыла ещё одна проблема: если каждый экран клиента всегда идёт через Gate к RAS, скорость интерфейса начинает зависеть от всей цепочки. Поэтому Hub хранит shadow-копию данных. По ней работают навигация и поиск, особенно когда запрос затрагивает несколько Gate или кластеров.
Но shadow — это всё-таки копия. Поэтому в API есть два способа получения данных. Обычные запросы читают shadow, а когда клиенту нужны свежие данные, он вызывает live-метод. Hub идёт через Gate к RAS, получает актуальное состояние и обновляет локальную копию.
Live-методы есть для списка кластеров и списка баз конкретного кластера. Поиск по нескольким Gate и кластерам работает по shadow: иначе один запрос пришлось бы превращать в обход всей инфраструктуры. Клиент сам выбирает, где ему нужны свежие данные, а где достаточно локальной копии.

RasStudio Mono
RasStudio Mono — экспериментальный локальный клиент на .NET, Blazor и Electron. Он запускает собственный Kestrel только на loopback-интерфейсе, хранит настройки локально в SQLite и собирается как отдельное desktop-приложение для Windows и Linux.
Клиент работает через API RasHub и не знает про запуск rac, особенности конкретной версии платформы и устройство Gate.

Где теперь проходят границы
Сейчас я разделяю ответственность так:
- RasGate — запуск
racс готовыми аргументами и контроль процесса; - RasHub — формирование аргументов, совместимость версий, объединение данных и API;
- клиент — пользовательские сценарии и интерфейс.
rac, учитывает версии и объединяет данные rac по HTTP rac Aможет обращаться кRAS #1RAS #2rac Bможет обращаться кRAS #3