gdmn icon indicating copy to clipboard operation
gdmn copied to clipboard

Актуализировать схему работы программы

Open gsbelarus opened this issue 5 years ago • 1 comments

  1. Для двух сценариев: с кластером и без.
  2. Последовательность действий которые происходят при запуске бэка, при запуске фронта, при конекте фронта к бэку (аутентификации), при выполненнии запросов, передаче данных, успехе и ошибках.
  3. Желательно указать участвующие объекты (с отсылкой к исходникам), методы и т.п.

Графическую картинку я сам потом нарисую по текстовому описанию.

gsbelarus avatar Apr 11 '19 16:04 gsbelarus

Взаимодействие фронта и бэка

Общая структура gdmn-back:

ADatabase

(source) Объект для работы с базой данных; Управляет всей работай с БД: создание/удаление подключение к базам данных, создание/удаление пула соединений для работы с БД и организацию работы с SQL выражениями через этот пул.

Application

(source) Приложение; Является наследником ADatabase. Отвечает за считывание и хранение ERModel, создание менеджера задач для работы с сессиями пользователей подключенных к данной БД, создание/хранение задач в очередях внутри сессий, создание пула childprocess-ов и организацию выполнения некоторых команд в этих процессах.

SessionManager

(source) Менеджер пользовательских сессий; Отвечает за создание/удаление/хранение пользовательских сессий. Подписан на изменения их статусов и уведомляет об этом другие модули системы. При открытии новой сессии синхронизирует общие задачи. При добавлении новых задач нужно вручную запускать синхронизацию.

Session

(source) Пользовательская сессия; Открывается при подключении пользователя к серверу. Умеет работать с пулом соединений и содержит дополнительный балансировщик нагрузки на них. Является хранилищем менеджера задач, данных о пользователе, используемых им соединениях и открытых ResultSet-ов. Имеет лимит времени жизни. Если пользователь, открывший сессию, отвалился из-за проблем со связью и не восстановил ее в пределах заданного количество времени - сессия считается закрытой и не может быть восстановлена. В тоже время если в контексте сессии есть работающие (RUNNING) задачи, она ждет их завершения и только после этого будет окончательно закрыта.

TaskManager

(source) Менеджер задач; Отвечает за хранение задач. Подписан на изменения их статусов и уведомляет об этом другие модули системы.

Task

(source) Задача; Отвечает за выполнение команды в контексте приложения. Содержит механизмы оповещения об изменении статуса и прогресса. Имеет лимит времени выполнения, который включается при переходе в состояние RUNNING. Если он превышен, а задача в процессе выполнения, то система просит ее прерваться. Так же содержит механизмы постановки выполнения задачи на паузу.

StompManager

(source) Менеджер стомп протокола; Отвечает за создание/удаление/хранение протокольных сессий и основного приложения.

StompSession

(source) Сессия стомп протокола; Является по сути своей обычным websocket соединением, поверх которого реализован STOMP протокол. Занимается всей комуникацией сетевого протокола с основной часть gdmn-back - приложением

index

(source) Точка входа gdmn-back; Создает http/https и websocket сервер, а так же менеджер стомп сессий. Инициализирует режим кластеризации. Превращает обычное websocket соединение в сессию стомп протокола.

Подключение к базе данных

Подключение к БД происходит через приложение или любой его наследник. Существует два вида наследников:

MainApplication

(source) База авторизация; Содержит информацию о все пользователях, а так же списки их приложений.

GDMNApplication

(source) База данных Gedemin либо пустая база данных, созданная пользователем.

Разница между подключением к этим двум типам БД с точки зрения протокола в том, что база авторизации является базой по умолчанию. Для подключения к БД гедемина нужно отправить uid приложения, который присваивается БД, при добавлении ее к пользователю в БД авторизации.

Для подключения к БД пользователь открывает websocket соединение, при этом создается стомп сессия. После этого фронт общается с бэком по stomp протоколу. Порядок работы с бэком:

  1. >>> CONNECT, в заголовке передаются данные для авторизации и uid приложения. В этот момент идет авторизация пользователя по БД авторизации, среди приложения пользователя происходит поиск по uid (если есть, иначе подключаемся к БД авторизации), инициализация подключения.
  2. <<< CONNECTED || <<< ERROR, передаются токены авторизации, id пользовательской сессии для возможности восстановления, либо ошибка авторизации или подключения приложения.
  3. >>> SUBSCRIBE делается 3 подписки: на статусы, прогресс и результат выполнения задач.
  4. >>> SEND при помощи этой командой происходит создание задачи на бэке. В заголовке передается тип команды, в теле - содержимое команды. После этого идет анализ всех входных данных в провайдере и вызовы нужных методов внутри приложения, для создания задач.
  5. <<< MESSAGE уведомления клиента по подпискам об изменении состояния задач. Если при создании или восстановлении сессии в ней есть задачи (ее собственные или полученные из других сессий), то отправляем их результаты, статусы и прогресс.
  6. >>> UNSUBSCRIBE делается 3 отписки.
  7. >>> DISCONNECT закрывает сессию без возможности восстановления.
  • Если на каком-либо этапе произошел разрыв соединения, происходит закрытие WebSocket (по heartbeat). Сессия на сервере, если успела создаться, переходит в режим ожидания восстановления, время которого задается через конфигурацию сервера.
  • Для подтверждения доставки и обработки сообщений на каждое серверное сообщение <<< MESSAGE клиент отправляет >>> ACK. Пока сервер не получит подтверждение, сообщение считается не доставленным и будет повторно отправлено при восстановлении сессии.

ChildProcess

ApplicationProcessPool

(source) Пул childProcess-ов; Занимается кэшированием использованных процессов и последующего их переиспользования.

ApplicationProcess

(source) ChildProcess; занимается кросспроцессным общением между приложениями (по сути легковесная замена слоя стомп протокола, где приложения в main процессе является клиентом, а в child процессе сервером). При создании подгружает полную копию приложения которое его создало.

При подключении приложения приложения создается пул процессов (только в main процессе), Любую задачу выполняющуюся в контексте этого приложения можно выполнить в другом процессе. Пример использования можно увидеть при загрузке ERModel. В этом случае при подключении приложения, после создания пула процессов, происходит проверка текущего процесса и если он является главным, то пересылка команды на получение модели в другой процесс, потом ожидаение ответа и возврат его как будто задача выполнялась внутри main процесса.

Cluster

Очень похоже на childProcess, за исключением того, что в другом процессе запускается не просто приложения, а сразу весь gdmn-back. При восстановлении сессии, нужно быть увереным что она попадет в тот же кластер, на каком и была до этого. Для это при установке webSocket соединения на сервер передается id процесса. После получения socket соединения на main процессе, идентифицируем нужный кластер или берем менее загруженный и перенаправляем socket ему, дальше отрабатывают все теже алгоритмы работы, что и без кластеризации.

sywka avatar Apr 19 '19 09:04 sywka