3.2 Разработка модели взаимодействия ПС
Диаграмма последовательности для программного средства приведена на рисунке 3.3.
Рисунок 3.3 – Диаграмма последовательности
Работа ПС основана на клиент-серверной архитектуре. Клиенты обоих типов – заказчики и исполнители – подключаются к серверу и проходят процедуру авторизации. В случае успешной авторизации на сервере создаются объекты сессии для подключившихся клиентов. В объекте сессии хранится уникальный идентификатор сессии и информация о клиенте: его тип, в случае клиента-исполнителя – его статус (занят/свободен), последнее сообщение о ходе выполнения, выполняемая задача и другие сведения.
Клиент-исполнитель сразу после авторизации отправляет на сервер запрос на выдачу ему задачи. Если задач в данный момент не имеется, клиент остаётся подключённым к серверу и ждёт появления задач. При этом соединение между ними поддерживается активным для того, чтобы в случае появления задачи моментально выдать её исполнителю. Но при очень большом количестве исполнителей такой алгоритм работы потребовал бы создания большого количества сокетов и открытых портов, количество которых в системе ограничено. Это могло бы создать проблемы при подключении новых заказчиков. Для избегания таких ситуаций применяется механизм «пула исполнителей», который заключается в ограничении количества одновременно ожидающих задач исполнителей. Это число задаётся в конфигурации сервера. Новые исполнители при попытки запроса задачи получают немедленный отказ с указанием причины – переполнение пула. На диаграмме 3.3 показан такой сценарий: при запросе 5 исполнитель получает отказ 6 с сообщением о переполнении пула исполнителей. В такой ситуации исполнитель должен выждать определённое время, после чего снова пытается получить задачу. Если к этому моменту пул будет освобождён, то он добавится в этот пул и начнёт ожидание задачи с открытым соединением. Такой механизм позволяет поддерживать нужное количество подключённых исполнителей, готовых моментально начать выполнять задачу при поступлении её от заказчика, и в то же время избежать открытия слишком большого количества портов на сервере.
Перед началом работы клиент-заказчик должен выполнить синхронизацию исполняемого модуля (операция 7 на диаграмме). Эта процедура состоит в отсылке на сервер модуля, содержащего исполняемый код, который необходим исполнителям для выполнения конкретных задач. Это может быть отдельная .NET-сборка либо – по умолчанию – просто само приложение пользователя.
При поступлении запроса на обработку от клиента-заказчика сервер сначала подготавливает полученную задачу, разделяя её на необходимое количество фрагментов – подзадач. Например, если задача состоит в распределённой обработке массива, то сервер должен разбить массив на N элементов, где N определяется так, чтобы обеспечить максимально быстрое выполнение задачи, учитывая количество подключённых исполнителей.
Если в пуле исполнителей находятся ожидающие задач клиенты, фрагменты исходной задачи отправляются им на обработку. При необходимости вместе с задачей исполнителю высылается полученный от заказчика модуль с исполняемым кодом. После этого исполнитель отключается от сервера и начинает выполнение задачи. В процессе выполнения он через определённые интервалы времени отправляет на сервер сообщение о ходе выполнения своей задачи. Это позволяет следить за процессом выполнения задач, а также обнаруживать ситуации сбоя на исполнителе. Если исполнитель по какой-либо причине аварийно завершается и не успевает известить об этом, сервер определяет это, потому что от клиента не поступало сигналов о ходе выполнения больше определённого отрезка времени. После этого клиент считается отключившимся и задача, которую он выполнял, отдаётся другому исполнителю. Такой механизм повышает отказоустойчивость системы.
После окончания обработки своей подзадачи исполнитель отправляет результат выполнения на сервер (операция 14 на диаграмме). Дождавшись результатов от всех клиентов-исполнителей, сервер объединяет их и отправляет сведённый результат заказчику (операция 15). На этом обработка конкретной задачи завершается.
|