02 Service и Host
Сервис
Сервис - это js класс наследуемый от Service, главный элемент системы.
Сервис
- имеет уникальное имя, обычно запускается в одном экземпляре
- может быть ограничен рабочим пространством(workspace), иначе он будет доступен во всех рабочих пространствах
- имеет схему сервиса, через которую описывает свои возможности, как публичные, так и приватные, доступные только другим сервисам
- запросы(request), могут вызваться из других сервисов или публично
- события(event), на которые могут быть подписаны другие сервисы
Для выполнения инициализации своего сервиса нужно перегрузить метод start.
import {Service} from "@morphcluster/core"
export default class Test extends Service {
async start() {
console.log("Starting")
}
}
stop работает по аналогии
Схема Сервиса
Схема используется для передачи между хостами, возможностей сервисов. Также, может использовтся для генерации клиентских и mock реализаций. Схема описывается через json такого вида:
{
name:"MyService",
requests: [
{
name:"run",
http: 'POST',
request:{
"type": "object",
"properties": {
"name": { "type": "string" },
"params": {},
},
"required": [ "name" ]
},
response:{},
description:"Выполнить метод",
}
]
}
Схему целиком можно установить через метод setSvcSchema(serviceSchema). Через метод getSvcSchema() можно получить текущую схему, вместе с добавленными изменениями отдельно.
Схема сервиса может содержать:
name
Имя сервиса, можно указать в сервисе через this.name = "NewName". По умолчанию высталяется автоматически имя класса.
requests
Массив, который описывает все запросы сервиса. Запрос состоит из:
-
name(string)- имя запроса, должно совпадать с именем метода, его реализующего -
description(string)- короткое описание -
request(object)- json schema параметров запроса, для валидации -
response(object)- json schema ответа, для валидации -
anonymous(boolean)- запрос можно вызвать без сессии, у авторизованного пользователя сессия будет приходить -
needAdmin(boolean)- снаружи, запрос может вызвать только администратор -
noLogs(boolean)- запрос не требует передавать ему логгер при вызове -
http(string)- запрос будет опубликован по HTTP, значение (GETилиPOST)
Методы в схему можно добавить отдельно, через вызов addRequest. Неопубиликованные методы нельзя будет иcпользовать за пределами хоста.
this.addRequest({
name : 'test',
request: {},
description:"..."
})
events
События вызываются внутри сервиса и на них могут быть подписаны другие сервисы, например для отслеживания изменений. Вызов события не имеют ответа.
Чтобы создать событие, надо объявить его в конструкторе сервиса и описать в схеме сервиса. Событие будет направлено в определенный workspace, указанный в первом параметре. События можно добавить в схему, аналогично addRequest, через addEvent, либо в общем json схемы.
import {Service, Event} from "@morphcluster/core"
...
export default class EvntSvc extends Service {
constructor(host) {
...
//Объявление собыия
this.onChanged = new Event()
//Добавление в схему
this.addEvent({
name: "onChanged",
description: "Данные изменились",
})
}
test() {
//Вызов события
this.onChanged.emit("myWorkspace", {"test":123})
}
}
Подписаться на вызов события можно через on. Второй аргумент - workspace, в который нужно отслеживать или null, чтобы принять событие из всех рабочих пространств.
this.EvntSvc.onChanged.on((payload)=>console.log(payload), "myWorkspace")
Структура схемы:
-
name(string)- имя события, должно совпадать с именем поля -
description(string)- короткое описание -
request(object)- json schema параметров, передаваемых в событии
Хост
Каждый процесс nodejs формирует хост, внутри которого запускаются сервисы, которые, по отношению друг к другу будут локальные. Чтобы локальные сервисы могли найти друг друга, их нужно добавить в созданный объект ServiceHost, а его экземпляр передать в конструктор.
ServiceHost - коллекция экземпляров сервисов, через которую разные сервисы взаимодействуют друг с другом.
Хранимые сервисы в ServiceHost можно добавлять как вручную, через addService, так и через ServiceFactory или другие сервисы. После добавления новый сервис автоматически запустится, если еще это не сделано.
import {ServiceHost} from '@morphcluster/core'
host = new ServiceHost()
host.addService(new HelloWorld(host))
Поучить запущенный сервис вручную из ServiceHost можно через метод requireService. Если сервис не закончил запуск, он не вернется.
ServiceRequire
Чтобы использовать сторонние сервисы в своем сервисе, можно наследовать свой класс от ServiceRequire.
Перед запуском, ServiceRequire дождется запуска всех своих зависимостей.
import {ServiceRequire} from "@morphcluster/core"
export default class HelloWorlds extends ServiceRequire {
constructor(host) {
super(host)
//Объявление поля для ссылки на зависимый сервис
//Для работы подсказок внутри IDE и лучшей читаемости кода
/** @type {Test} */
this.HelloWorld = null
//Список зависимостей
this.requrements = [ "HelloWorld" ]
}
async start() {
await super.start()
//Вызов метода из другого сервиса, после super.start
await this.Test.test({}, "common", null)
}
}
No Comments