Origami
Origami — мультиплатформенная библитека, которая дает гарантию доставки запроса и ответа вне зависимости от сетевых сбоев. Размещайте сервисы в разных зонах и не обращайте внимание на качество канала между ними.
Возможности
- микросервисная архитектура
- гарантия доставки запроса
- гарантия доставки ответа
- мультиплатформенность
- возможность управлять конкурентностью запросов
- конкурентные запросы с разделением по ключу
- отложенная доставка запроса
- балансировка round-robin
- предотвращение дублирования запросов
Зависимости
Для работы необходим Redis. Вся разработка велась на версии Redis 6.2.
Ответственность
Origami гарантирует доставку при нестабильной работе сети. В случае непредвиденной остановки Redis или вашего приложения часть данных может быть потеряна или повреждена. Вы должны сами следить за работаспособностью Redis и вашего приложени.
Установка
Установка производится с помощью менеджера пакетов NPM
npm install @zaycev.dev/origami
Использование
Пример использования, запуск простого сервиса
import {Origami} from '@zaycev.dev/origami';
// инициализация клинта
const origami = new Origami({
noneName: 'eu-west-01',
appName: 'Sample service',
connection: {
host: 'redis.host',
port: 6379,
},
password: 'redispassword',
});
// интерфейты параметров запроса и ответа
interface IParams {
foo: number;
bar: number;
};
interface IResponse {
sum: number;
}
// инициализация сервиса
origami.channel<IParams, IResponse>('math.sum', {concurrent: 1}, async (params: IParams, requestId: string, senderId: string): Promise<IResponse> => {
const foobar = params.foo + params.bar;
return {
sum: foobar,
};
});
// запуск клиента
await origami.start();
// запрос к сервису
const sum = await origami.request<IResponse, IParams>('math.sum', {foo: 1234, bar: 4321});
// остановка клиента
await origami.stop();
Описание параметров
Параметры инициализации клиента
параметр | обязателен | тип | описание |
---|---|---|---|
nodeName | нет | string | Имя ноды |
appName | нет | string | Имя приложения |
appVersion | нет | string | Версия приложения |
connection | да | object | Данные для подключения к Redis |
connection.host | да | string | Хост Redis |
connection.port | да | number | Порт Redis |
password | нет | string | Пароль для Redis |
onConnect | нет | function() | Колбек при успешном подключении |
onReconnect | нет | function() | Колбек при успешном переподключении |
onClose | нет | function() | Колбек при разрыве соединения |
onError | нет | function(error: Error) | Колбек при ошибке |
reconnectTimout | нет | number | Время переподключения |
Парамеры создания канала
origami.channel(channelName, channelOptions, channelHandler(parameters, requestId, senderId));
параметр | обязателен | тип | описание |
---|---|---|---|
channelName | да | string | Имя канала (доступные символы [a-zA-Z0-9.-_]) |
channelOptions | да | object | Параметры канала |
channelOptions.concurrent | нет | number | Количество одновременно исполняемых запросов в канале. 0 - без ограничений, при указании группы в параметрах запроса ограничение накладывается на группу |
channelHandler | да | function | Функция - обработчик запроса |
channelHandler.parameters | да | any | Параметры запроса |
channelHandler.requestId | да | string | ID запроса |
channelHandler.senderId | да | string | ID отправителя запроса |
Параметры отправки запроса
origami.request(channelName, parameters, options);
параметр | обязателен | тип | описание |
---|---|---|---|
channelName | да | string | Имя канала (доступные символы [a-zA-Z0-9.-_]) |
parameters | да | any | Параметры запроса |
options | нет | object | Опции запроса |
options.group | нет | string | Разделение на группы (для конкурентного исполнения в разрезе канала/группы) |
options.tryAfter | нет | number | Время исполнения запроса (отложенный запрос). Время указывается в UNIX-timestamp в секундах |
options.timeout | нет | number | Максимальное время нахождения в мемпуле (до того как запрос был достален слушателю канала). В секундах |
options.noResponse | нет | boolean | Не ожидать ответ (после регистрации запроса отправитель сразу получит ответ и не будет ждать пока слушатель получит и обработает запрос) |
Тело ответа
const response = await origami.request(...);
const {
ok,
code,
result,
executorId,
} = response;
параметр | обязателен | тип | описание |
---|---|---|---|
ok | да | boolean | Признак успешности запроса |
code | да | enum(EResponseCode) | При неуспешном запросе возможные значения: EResponseCode.UNEXPECTED_ERROR - необработанная ошибка в функции-обработчике. В result будет тело ошибки в формате платформы исполниения EResponseCode.TIMEOUT_ERROR - было превышено время нахождения в мемпуле. Не нашлось исполнителя или забита очередь исполнения. В result будет null
|
result | да | any | При успешном запросе будет тело ответа из функции-обработчика |
executorId | да | string/null | ID слушателя, который обработал запрос. При code === EResponseCode.TIMEOUT_ERROR поле будет равно null
|
License
Origami is available under the MIT license.
Contact
Copyright (c) 2023 Origami