Cервис на Go для вычисления арифметических выражений. Сервис принимает математические выражения через POST-запросы и возвращает вычисленные результаты.
- Асинхронное вычисление арифметических выражений
- Поддержка базовых арифметических операций (+, -, *, /)
- Поддержка скобок для управления порядком операций
- Формат обмена данными JSON
- Распределённое выполнение операций между агентами
- История вычислений с подробной информацией
- Веб-интерфейс для удобного использования
- Обработка ошибок с соответствующими HTTP-кодами
- Установленный Go (версия 1.20 или выше)
- Node.js 18+ и npm (для фронтенда)
- Docker и Docker Compose (для запуска через Docker)
- Make (опционально, для упрощения запуска)
Для удобства запуска всех компонентов системы используйте команды Make:
# Клонирование репозитория
git clone https://github.com/neptship/calc-yandex-go
cd calc-yandex-go
# Установка всех зависимостей (Go модулей и npm пакетов)
make install
# Запуск всех компонентов (оркестратор, агент, фронтенд)
make run-all
Проект поддерживает запуск через Docker и Docker Compose:
git clone https://github.com/neptship/calc-yandex-go
cd calc-yandex-go
docker-compose up
Клонирование репозитория и установка зависимостей
# Клонирование репозитория
git clone https://github.com/neptship/calc-yandex-go
cd calc-yandex-go
# Установка Go модулей
go mod tidy
# Установка npm пакетов
cd frontend
npm install
cd ..
Запуск оркестратора
go run cmd/orchestrator/main.go
Запуск агентов (В отдельном терминале)
go run cmd/agent/main.go
По умолчанию оркестратор запускается на порту 8080.
cd frontend
npm run dev
Веб-интерфейс будет доступен по адресу: http://localhost:3000
flowchart LR
A[Фронтенд Next.js] -->|Отправка выражения| B[Оркестратор Go]
B -->|Задачи с указанным временем| C[Агенты Go]
C -->|Результаты операций| B
B -->|Итоговый ответ| A
Отправляет выражение на вычисление и возвращает идентификатор задачи.
Формат запроса:
{
"expression": "2+2*2"
}
Успешный ответ (201 Created):
{
"id": 1
}
Ответ при некорректном выражении (422 Unprocessable Entity):
{
"error": "invalid expression"
}
Ответ при внутренней ошибке сервера (500 Internal Server Error):
{
"error": "internal server error"
}
Получает статус и результат вычисления по идентификатору.
Успешный ответ (200 OK), вычисление завершено:
{
"expression": {
"id": 1,
"status": "completed",
"result": 6
}
}
Успешный ответ (200 OK), вычисление в процессе:
{
"expression": {
"id": 1,
"status": "processing"
}
}
Выражение не найдено (404 Not Found):
{
"error": "Expression not found"
}
Получает список всех выражений и их статусов.
Успешный ответ (200 OK):
{
"expressions": [
{
"id": 1,
"status": "completed",
"result": 6
},
{
"id": 2,
"status": "processing"
}
]
}
Получает задачу для выполнения агентом.
Успешный ответ (200 OK):
{
"task": {
"id": 1,
"arg1": 2,
"arg2": 2,
"operation": "+",
"operation_time": 1000
}
}
Ответ, если нет доступных задач (404 Not Found):
{
"error": "No tasks available"
}
Отправляет результат выполнения задачи.
Формат запроса:
{
"id": 1,
"result": 4
}
Успешный ответ (200 OK):
{
"success": true
}
Ответ, если задача не найдена (404 Not Found):
{
"error": "Task not found"
}
Отправка выражения на вычисление
curl --location 'http://localhost:8080/api/v1/calculate' \
--header 'Content-Type: application/json' \
--data '{
"expression": "2+2*2"
}'
Ответ:
{
"id": 1
}
Отправка сложного выражения
curl --location 'http://localhost:8080/api/v1/calculate' \
--header 'Content-Type: application/json' \
--data '{
"expression": "(70/7) * 10 /((3+2) * (3+7)) - 2"
}'
Ответ:
{
"id": 2
}
Получение результата вычисления
curl --location 'http://localhost:8080/api/v1/expressions/1'
Ответ:
{
"expression": {
"id": 1,
"status": "completed",
"result": 6
}
}
Получение списка всех выражений
curl --location 'http://localhost:8080/api/v1/expressions'
Ответ:
{
"expressions": [
{
"id": 1,
"status": "completed",
"result": 6
},
{
"id": 2,
"status": "processing"
}
]
}
Получение задачи агентом
curl --location 'http://localhost:8080/internal/task'
Ответ:
{
"task": {
"id": 3,
"arg1": 3,
"arg2": 5,
"operation": "+",
"operation_time": 1000
}
}
Отправка результата задачи
curl --location 'http://localhost:8080/internal/task' \
--header 'Content-Type: application/json' \
--data '{
"id": 3,
"result": 8
}'
Ответ:
{
"success": true
}
Невалидный JSON при отправке выражения
curl --location 'http://localhost:8080/api/v1/calculate' \
--header 'Content-Type: application/json' \
--data 'not-valid-json'
Ответ:
{
"error": "Invalid request format"
}
curl --location 'http://localhost:8080/api/v1/calculate' \
--header 'Content-Type: application/json' \
--data '{
"expression": "2+*2"
}'
Ответ:
{
"error": "invalid expression"
}
Запрос несуществующего выражения
curl --location 'http://localhost:8080/api/v1/expressions/999'
Ответ:
{
"error": "Expression not found"
}
Деление на ноль
curl --location 'http://localhost:8080/api/v1/calculate' \
--header 'Content-Type: application/json' \
--data '{
"expression": "5/0"
}'
После проверки статуса выражения:
{
"expression": {
"id": 3,
"status": "failed",
"result": null
}
}
Запрос задачи, когда нет доступных задач
curl --location 'http://localhost:8080/internal/task'
Ответ:
{
"error": "No tasks available"
}
Некорректный запрос при отправке результата задачи
curl --location 'http://localhost:8080/internal/task' \
--header 'Content-Type: application/json' \
--data 'not-valid-json'
Ответ:
{
"error": "Invalid request body"
}
Отправка результата для несуществующей задачи
curl --location 'http://localhost:8080/internal/task' \
--header 'Content-Type: application/json' \
--data '{
"id": 999,
"result": 42
}'
Ответ:
{
"error": "Task not found"
}
Система настраивается через переменные окружения:
PORT
- порт для HTTP-сервера (по умолчанию 8080)COMPUTING_POWER
- количество параллельных вычислителей в агенте (по умолчанию 3)TIME_ADDITION_MS
- время выполнения сложения (по умолчанию 1000 мс)TIME_SUBTRACTION_MS
- время выполнения вычитания (по умолчанию 1000 мс)TIME_MULTIPLICATIONS_MS
- время выполнения умножения (по умолчанию 1500 мс)TIME_DIVISIONS_MS
- время выполнения деления (по умолчанию 2000 мс)
- Поддерживаются только положительные целые числа
- Использование унарного минуса или плюса приведет к некорректной работе
- Поддерживаются только POST-запросы
- Все нестандартные символы в выражении (буквы, спецсимволы) приведут к ошибке 422
Веб-интерфейс предоставляет следующие возможности:
- Ввод арифметических выражений
- Отображение прогресса вычислений в реальном времени
- История вычислений с результатами
- Просмотр подробной информации в JSON-формате
- Очистка истории
# Запуск всех тестов
cd calc-yandex-go
make test
# или напрямую
go test ./... -v
- Рекомендуется использовать Postman для тестирования API, так как с curl могут возникнуть проблемы
- При использовании curl рекомендуется выполнять запросы через git bash терминал
- Для тестирования асинхронных вычислений сделайте запрос, а затем периодически запрашивайте результат
/calc-yandex-go/
├── cmd/ # Точки входа для исполняемых файлов
│ ├── orchestrator/ # Оркестратор
│ └── agent/ # Агент
├── internal/ # Внутренние пакеты
│ ├── agent/ # Логика агента
│ ├── config/ # Конфигурация
│ ├── models/ # Модели данных
│ └── orchestrator/ # Логика оркестратора
├── pkg/ # Переиспользуемые пакеты
│ └── calculation/ # Парсинг и вычисление выражений
├── frontend/ # Next.js фронтенд
└── docker-compose.yml # Конфигурация Docker