Чем тяжелее писался код, тем тяжелее он должен читаться.
Добро пожаловать в слепок неудавшегося творца. Это ультрамощный калькулятор, работающий на Майорановских фермионах.
Если они сломались и вы готовы дать время на доработку, отправтье Issue, я все исправлю. Спасибо!
Что за докер?
Для работы проекта нужен Docker. Он позволяет запустить оркестратор, агент и фронтенд как-будто они находятся на разных серверах. Для этого по инструкции docker-compose.yml Докер находит Dockerfile каждого сервиса, пробрасывает порты и тп. Из Dockerfile создается образ, из которого уже делается индивидуальный контейнер. В итоге их будет 3.
Докер кроссплатформенный и для всех ОС работает одинаково. Можно скачать Docker Desktop, особенно это удобно для Windows.
-
Запустите движок Docker (или откройте Docker Desktop).
-
В cmd или Bash из корня проекта:
docker-compose up --build
Первый запуск может занять пару минут, поскольку качается официальный go-образ с Docker Hub. В итоге вы получите консоль с логами от всех сервисов. Чтобы выйти, нажмите ctrl+c.
Флаг --build ищет изменения в файлах и в случае таковых, пересобирает нужную часть. Повторите эту команду при внесении изменений.
Чтобы удалить все контейнеры и образы, связанные с этим проектом, напишите из корня проекта:
docker-compose down --rmi all
После запуска, вам будет доступно:
-
http://localhost:8080-- фронтенд (хотя бы одним глазком...). -
http://localhost:8081/...-- api оркестратора. К нему обращается бразуерный фронтенд и ловит ха-ха. Куда конкретно и как правильно (на вы) обращаться, будет написано чуть ниже.
Всего в проекте 3 сервиса:
- calculationService
- megaFastAGent
- webApp
Кроме докерфайлов есть кое-что еще. Код и .env, к переменным которого обращаются все нижеуказанные сервисы.
Это api, точка сбора всех эндпоинтов и некоторых багов, которые можно поймать.
Состоит из http сервера и калькулятора.
В случае ошибки во время вычисления одной из задач сбрасывает все другие через context.
calculationService/
|-- cmd/
|-- main.go -- точка входа
|-- internal/
|-- app/
|-- orchestrator.go -- сервер с хэндлерами и точка входа для выражения
|-- pkg/
|-- calculator/
|-- tokenize.go -- токенизация из строки в структуру с числами, скобками и знаками
|-- buildTree.go -- построение дерева из токенов
|-- calculate.go -- обход по дереву, хранение и направление задач Агенту через Оркестратор
|-- Dockerfile
|-- go.mod
Очень быстрый агент и настоящий мастер в своем деле. Выполняет простейшие математические операции. Иногда возвращает ошибку выражения (например, поделить на нуль). Еще в нем есть простой кэш со старыми ответами.
megaFastAgent/
|-- cmd/
|-- main.go -- точка входа
|-- internal/
|-- agent/
|-- app.go -- конфигурация
|-- errors.go -- список ошибок
|-- logger.go -- простейший логгер
|-- service.go -- основной функционал
|-- Dockerfile
|-- go.mod
Просто выдача фронтенда, доступная по адресу http://localhost:8080.
ЯвАсКрИпТ код слегка валидирует ваш ввод и отправляет на соответсвующий эндпоинт API (через plain/text, потому что CORS ограничения и все дела). После чего раз в секунду проверяется результат нового выражения, и если его статус отличен от pending, то прекращает и обновляет данные в соответствующем элементе.
webApp/
|-- cmd/
|-- main.go -- просто сервер для файлов
|-- static/
|-- assets/... -- папка для шрифтов и картинок
|-- fonts.css
|-- images.css
|-- style.cc
|-- script.js
|-- index.html
|-- Dockerfile
|-- go.mod
Если вы предпочли не пользоваться фронтендом.
/api/v1/calculate
На запрос с методом POST и телом:
{
"expression": "ваше выражение"
}
Вернет со статусом 201:
{
"id": "Id выражения"
}
На невалидное тело статус 422 и сообщение об ошибке.
/api/v1/expressions
На запрос с методом GET.
Возвращает список всех выражений:
{
"expressions": [
{
"id": "Id первого выражения",
"status": "pending", "resolved" или "error",
"result": число с результатом или 0 в случае ошибки
},
{
"id": "Id первого выражения",
"status": "pending", "resolved" или "error",
"result": число с результатом или 0 в случае ошибки
}
]
}
/api/v1/expressions/идентификатор_выражения
На запрос с методом GET.
Возвращает только одно выражение:
{
"expression":
{
"id": "Id первого выражения",
"status": "pending", "resolved" или "error",
"result": число с результатом или 0 в случае ошибки
}
}
Если его нет, 404.
/internal/task
Этот эндпоинт предназначен для агента. Лучше не лезть! Чтобы взаимодействовать, можете использовать заголовок
Authorizationсо значениемAPI_TOKENиз.env. Вот оно, кстати,VOROVSKAYA_LAPA. Но тогда вы будете обязаны посчитать и вернуть результат.
На запрос с методом GET.
Возвращает задачу (и больше он эту задачу не покажет):
{
"task":
{
"id": "Id задачи",
"arg1": число 1,
"arg2": число 2,
"operation": руна, соответсвующая знаку операции,
"operation_time": время на выполение, в миллисекундах
}
}
404 -- задач пока нет, но они могут ещё появиться.
На запрос с методом POST и телом:
{
"id": "Id задачи",
"result": результат выражения, если ошибка -- "error"
}
Отвечает
- 200 - успешно записан результат
- 404 - нет такой задачи
- 422 - невалидные данные
- 500 - что-то пошло не так