Skip to content

emresha/distributed-arithmetic-expression-calculator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Распределённый вычислитель арифметических выражений 2

Первый проект Яндекс.Лицея по языку Go.
Очень сильно приветствуется обоснованное открытие Issues, Pull Request'ов и т.п.:)
В случае проблем при проверке просьба связаться со мной в tg: @justanaveragetelegramuser

Условие

Пользователь хочет считать арифметические выражения. Он вводит строку 2 + 2 * 2 и хочет получить в ответ 6. Но наши операции сложения и умножения (также деления и вычитания) выполняются "очень-очень" долго. Поэтому вариант, при котором пользователь делает http-запрос и получает в качестве ответа результат, невозможна. Более того, вычисление каждой такой операции в нашей "альтернативной реальности" занимает "гигантские" вычислительные мощности. Соответственно, каждое действие мы должны уметь выполнять отдельно и масштабировать эту систему можем добавлением вычислительных мощностей в нашу систему в виде новых "машин". Поэтому пользователь может с какой-то периодичностью уточнять у сервера "не посчиталость ли выражение"? Если выражение наконец будет вычислено - то он получит результат. Теперь это многопользовательский проект с использованием СУБД и gRPC.

Важное допущение!

Размытость условия задачи позволяет сделать некоторое допущение. Допущение заключается в том, что все числа, вводимые пользователем - целые (да и в целом в нашей "альтернативной реальности" нет вещественных чисел), а первое число - неотрицательное. пример ошибочных выражений (они выдадут ошибку 422 Unprocessable Entity):

  • -1 + 3, но можно написать так 3 - 1;
  • -1 * 3, но можно записать как 3 * -1;
  • 1.0 + 3;
  • a + b;
  • abc. ... и тому подобное.
    Также ввод только числа, т.е. выражения без арифметических знаков, считается за ошибочный ввод и будет возвращать 422. Например: 4, 441241, 1, 21 и т.д.

Зависимости

  • Go 1.22.2.
  • gRPC
  • protobuf
  • SQLite3
  • и ещё в go.mod

Инструкция по запуску

Запуск вручную

Порядок запуска оркестратора и агента не важен.
Если запускать Оркестратор или Агента не из папки, указанной в инструкции, то могут быть ошибки (и скорее всего будут!) с обнаружением config.cfg файла и базы данных. Так что, пожалуйста, чётко следуйте инструкции, и запускайте Агента и Оркестратора находясь в их папке.

  1. Убедитесь, что у вас установлены все зависимости;
  2. Убедитесь, что вы находитесь в корневой папке проекта: distributed-arithmetic-expression-calculator/.;
  3. По желанию можете изменять значения переменных окружения в файле config.cfg.
  4. Перейдите в папку с агентом: Linux/MacOS: cd cmd/agent, Windows: cd .\cmd\agent\;
  5. Запустите агента go run main.go;
  6. Не закрывая текущий терминал, запустите ещё один терминал и переместитесь из корневой папки проекта в папку с оркестратором: Linux/MacOS: cd cmd/orchestrator, Windows: cd .\cmd\orchestrator\;
  7. Запустите оркестратор go run main.go;
  8. Перейдите по ссылке localhost:8080.

Структура проекта

distributed-arithmetic-expression-calculator/
├── api
│   └── handler
│       └── handler.go    # Все "ручки" обрабатываются здесь
├── cmd
│   ├── agent             # Агент
│   │   └── main.go
│   └── orchestrator      # Оркестратор вместе с базой данных
│       ├── data.db
│       └── main.go
├── config
│   └── config.go         # Обработка конфига
├── config.cfg            # Конфиг
├── go.mod
├── go.sum
├── internal
│   ├── logic
│   │   └── calculate.go  # Внутренняя очень сложная логика подсчёта и параллелизации выражений
│   └── service
│       └── service.go    # Определения структур и полезные функции
├── LICENSE
├── proto                 # Всё от protobuf
├── README.md             # Файл, который вы читаете:)
└── static                # Содержимое веб-страниц

Структура базы данных

image

Как это работает

После запуска Оркестратора и Агента, последний запускает указанное количество горутин и ежесекундно делает gRPC запрос Оркестатору с целью получить задачу на подсчёт.
Оркестратор, в свою очередь, получает из базы данных Такси (service.Task, заданное пользователем выражение) и Операции (service.Calculation, простые выражения, на которые разбивается Таска, по типу 2 + 2) и, если есть какие-то Операции в ожидании подсчёта, отправляет их агенту.
Агент меняет их статус на "подсчитываются". Оркестратор, получая Таску от пользователя, проверяет данные на правильность и тому подобное, в случае правильности данных отправляет Таску на разбитие на простые Операции, а также пытается "параллелизировать" некоторые Операции Таски.
Оркестратор, получая посчитанную Операцию от Агента, проверяет, не возникло ли ошибок во время подсчёта (деление на ноль) и, если не возникло, то подставляет результат в выражение Таски. Если после этого от выражения Таски осталось только одно число, значит всё посчитано, и Таска готова к отправлению обратно пользователю.

Как это работает для обычного пользователя

После запуска оркестратора и агента, пользователь переходит на localhost:8080 и сразу же перенаправляется на /auth (он же не авторизован, так что логично, но если каким-то чудом у него есть действующий токен, то он не будет перенаправлен), на этой странице он регистрируется и входит, и получает токен на пятнадцать минут с перенаправлением на /. После этого он может вводить свои выраженьица.

Примеры работы и дополнительные объяснения

YouTube

Поддержать проект

Любая конструктивная критика приветствуется (в Issues) :) Также можете поставить звёздочку проекту, будет очень приятно!

About

First Yandex.Lyceum Golang Project

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published