Потребуется развернутая кафка на порту 9092. Запросы отправлять http://localhost:4444/facts/save_fact
Учтена отказоустойчивость и консистентность. Если буфер упадёт, то запросы не будут потеряны, когда буфер восстанвоится после падения, отправка запросов на сервер продолжится.
-
Прием запроса:
МетодSave
вызывается при поступлении HTTP POST запроса. В нем происходит проверка метода, парсинг и валидация данных формы, а затем сохранение JSON-представления факта в хранилище. -
Асинхронная обработка:
МетодServe
непрерывно извлекает сохраненные сообщения из хранилища после того как предидущий запрос был выполнен. Для каждого сообщения:- Сообщение десериализуется в структуру
fact.Fact
. - Формируется HTTP запрос для отправки данных на внешний API с помощью функции
createRequest
. - Сообщение подтверждается в хранилище.
- Запрос отправляется с использованием объекта
writer
. - Результат отправки логируется.
- Сообщение десериализуется в структуру
-
Завершение работы:
МетодStop
отправляет сигнал через каналstopCh
, что приводит к корректному завершению бесконечного цикла в методеServe
.
-
storage (storage.Storager):
Интерфейс для сохранения, получения и подтверждения сообщений. Это позволяет абстрагироваться от конкретной реализации хранилища. -
writer (writer.Writer):
Объект, отвечающий за отправку HTTP запросов, инкапсулирующий логику исходящих вызовов. -
token:
Bearer токен для аутентификации запросов треубется передать черезenv variables
в переменнуюTOKEN
, отправляемых на внешний API. -
stopCh (chan struct{}):
Канал для сигнализации остановки сервера.
Инициализирует и возвращает новый экземпляр BufferAPIServer
с заданными параметрами:
- Устанавливает хранилище, writer, токен и канал остановки.
Обрабатывает входящие HTTP POST запросы.
- Проверка метода:
Если метод запроса не POST, возвращается ошибка 405 (Method Not Allowed). - Парсинг формы:
Используетсяr.ParseMultipartForm(10 << 20)
для парсинга данных формы с лимитом в 10 МБ. - Валидация и преобразование:
ФункцияparseRequest
извлекает значения из формы, конвертируя их в соответствующие типы (например, строки в числа). При ошибках валидации возвращается сообщение об ошибке и статус 400 (Bad Request). - Сохранение данных:
Факт преобразуется в JSON и сохраняется в хранилище. При ошибке сохранения возвращается статус 500 (Internal Server Error). - Ответ:
При успешной обработке возвращается статус 200 (OK) и выводится сообщение "OK".
Извлекает и преобразует значения формы из HTTP запроса в структуру fact.Fact
:
- Читает поля формы с помощью
r.FormValue
. - Преобразует числовые поля с использованием
strconv.Atoi
. - В случае ошибки преобразования возвращает сообщение об ошибке и статус 400.
Создает новый HTTP POST запрос для отправки данных факта на внешний API.
- Формирование тела запроса:
Создается тело запроса в форматеmultipart/form-data
с помощьюmultipart.NewWriter
. Каждое поле факта записывается с помощьюwriter.WriteField
. - Создание запроса:
Формируется новый POST запрос к URLhttps://development.kpi-drive.ru/_api/facts/save_fact
. - Установка заголовков:
УстанавливаетсяContent-Type
с указанием boundary и заголовокAuthorization
с Bearer токеном.
Запускает бесконечный цикл для асинхронной обработки сохраненных сообщений.
- Основной цикл:
Цикл проверяет наличие сигнала остановки через каналstopCh
. Если сигнал получен, цикл завершается. - Обработка сообщений:
В цикле вызывается методprocess
для обработки одного сообщения за раз. При ошибках производится логирование.
Обрабатывает одно сообщение из хранилища.
- Получение сообщения:
Извлекает сообщение из хранилища. - Десериализация:
Преобразует JSON сообщение в структуруfact.Fact
. - Создание запроса:
С помощьюcreateRequest
формируется HTTP запрос для отправки данных на внешний API. - Подтверждение:
После успешного создания запроса вызывается метод подтверждения обработки сообщения (s.storage.Confirm
). - Отправка:
Запрос отправляется черезs.writer.Write
. - Логирование:
Производится логирование успешной отправки или ошибки, если таковая возникла.
Сигнализирует серверу о необходимости остановить цикл обработки, отправляя сигнал через канал stopCh
.
Написаны тесты для методов Serve и Save