Есть следующий кейс:
1. клиент отправляет заявку, заявка создается, но ответ от сервера не был получен, интернет вообще пропал на какое-то время
2. проходит какое-то время
3. сервер начинает шедулить заявки: искать дубли заявок и выбирать исполнителя.
4. сервер назначает водителя
5. у клиента отвисает интернет и он повторяет исходный запрос создания заявки
6. создается дублирующая заявка
7. по этой дублирующей заявке позже приезжает второе такси
Не понимаю идеи, чем заявки на создание заказа помогают?
Здесь та же проблема: на шаге 5 сервер мог получить подтверждение о получении заказа, но клиент об этом не узнает (не получив ответ). Если тогда через 1-2 минуты клиент покажет ошибку — пользователь подумает, что такси заказать не удалось, но машина неожиданно приедет.
В простейшей реализации выбор стоит не между 0 и 2 SMS, а между 0 и n (например, 100) SMS. Я сталкивался на одном из прошлых мест работы с тем, как пользователю приходят десятки сообщений из-за подобной логики.
Можно пытаться запоминать в базе число попыток отправить SMS и применять at least once семантику на первые 3 попытки, а потом отбрасывать. Но здесь есть схожая проблема: что если произошел таймаут при запоминании факта попытки отправки SMS: выбирать at least once, или at most once семантику.
Обычно, семантика выбирается в зависимости от важности конкретного типа SMS.
Локальная база в какой-то степени обычно используется. И, подозреваю, что с ней тоже могут быть тайм-ауты, и надо немного думать про идемпотентность.
Если, например, изменять заказы сначала локально, а потом синкать на сервер, то либо придётся жертвовать мультидевайсностью (показывать все заказы на всех устройствах), либо решать проблему синхронизации изменений при изменении заказа с двух устройств около-одновременно.
оу, в ридми ошибка, megacheck по умолчанию включен, спасибо. И, действительно, megacheck это самый медленный линтер.
golangci-lint быстрее за счет того, что:
Он загружает программу и проверяет ее типы только 1 раз: это 80% работы большинства линтеров.
Он парсит AST дерево не для каждого линтера: для части линтеров переиспользуется уже распаршенное дерево. В плане делать это для всех.
Нет создания процессов и использования больше потоков, чем доступно процессоров или указал пользователь. С запущенным gometalinter из-за этого, в частности, за ноутом невозможно работать: он есть все ядра, в не столько, сколько ему указал.
Умный планировщик линтеров, учитывающий их время выполнения
Спасибо за статью и использование golangci-lint, я, как его автор хотел бы дополнить двумя пунктами:
Рекомендую устанавливать фиксированную версию, а не через go get (увидел это в докерфайле): так билды в CI будут стабильнее при улучшении существующих линтеров
Есть классные опции --new/--new-from-rev: они здорово помогают интегрироваться в крупные проекты — ошибки ищутся только в новом коде. Например, так смогли применить golint в GoogleContainerTools/skaffold.
И было бы здорово ссылку на проект добавить, по аналогии с goreporter и gometalinter.
1. клиент отправляет заявку, заявка создается, но ответ от сервера не был получен, интернет вообще пропал на какое-то время
2. проходит какое-то время
3. сервер начинает шедулить заявки: искать дубли заявок и выбирать исполнителя.
4. сервер назначает водителя
5. у клиента отвисает интернет и он повторяет исходный запрос создания заявки
6. создается дублирующая заявка
7. по этой дублирующей заявке позже приезжает второе такси
Не понимаю идеи, чем заявки на создание заказа помогают?
Здесь та же проблема: на шаге 5 сервер мог получить подтверждение о получении заказа, но клиент об этом не узнает (не получив ответ). Если тогда через 1-2 минуты клиент покажет ошибку — пользователь подумает, что такси заказать не удалось, но машина неожиданно приедет.
В простейшей реализации выбор стоит не между 0 и 2 SMS, а между 0 и n (например, 100) SMS. Я сталкивался на одном из прошлых мест работы с тем, как пользователю приходят десятки сообщений из-за подобной логики.
Можно пытаться запоминать в базе число попыток отправить SMS и применять at least once семантику на первые 3 попытки, а потом отбрасывать. Но здесь есть схожая проблема: что если произошел таймаут при запоминании факта попытки отправки SMS: выбирать at least once, или at most once семантику.
Обычно, семантика выбирается в зависимости от важности конкретного типа SMS.
Локальная база в какой-то степени обычно используется. И, подозреваю, что с ней тоже могут быть тайм-ауты, и надо немного думать про идемпотентность.
Если, например, изменять заказы сначала локально, а потом синкать на сервер, то либо придётся жертвовать мультидевайсностью (показывать все заказы на всех устройствах), либо решать проблему синхронизации изменений при изменении заказа с двух устройств около-одновременно.
golangci-lint быстрее за счет того, что:
И было бы здорово ссылку на проект добавить, по аналогии с goreporter и gometalinter.