Ваш застосунок для водіїв має працювати в клітці Фарадея
Логістичний застосунок, що передбачає з'єднання, зламається у виробництві приблизно на третій день. Будівництво офлайн-first — це не преміум-інженерія, а єдиний вид, що виходить у реліз.
Найкорисніша вправа, яку ми проводимо для нового логістичного клієнта — це тест ліфта. Беремо телефон водія і заходимо у вантажний ліфт на вантажному дворі. Закриваємо двері. Дивимося на застосунок.
Якщо застосунок перетворюється на спіннер, зависає, втрачає місце користувача або — найпоширеніша помилка — мовчки губить скан, який водій щойно виконав, застосунок не готовий до виробництва. Водії проводять значну частину дня в сталевих коробках, бетонних будівлях, сільських мертвих зонах і тунелях. Зв'язок — це не властивість, яку вони мають. Це властивість, яку вони іноді мають.
Таке реальне обмеження. Будувати для нього — це не преміум-інженерія, а єдиний вид, що виходить у реліз.
Три режими збою, які вражають команди щоразу
Після достатньої кількості логістичних проектів три режими збою з'являються знову й знову.
Оптимістичний запис, якого не було. Водій сканує пакет. Застосунок показує "відскановано". Сервер через мережевий збій запис не отримав. Водій вважає, що пакет у системі; система — ні. Пакет потрапляє на наступну зупинку, і ніхто не знає, що з ним робити. Першопричина: застосунок показав успіх на основі локальної дії без підтвердження від сервера і без способу для водія дізнатися про різницю.
Логін, якому потрібна мережа. Водій з'являється на початку зміни, і телефон втратив сесію. Екран входу мусить звернутися до auth-сервера. Водій стоїть на парковці з двома поділками покриття, які падають до нуля, щойно вантажівка рушає. Зміна не може почастися. Кожна хвилина — оплачуваний час, і телефон диспетчера вже дзвонить.
Черга "синхронізую пізніше", яка губить дані. Багато команд будують офлайн-підтримку, ставлячи дії в чергу локально і синхронізуючи при відновленні мережі. Це працює, поки черга не переростає обсяг пристрою, або користувач закриває застосунок і черга губиться, або код синхронізації має баг і мовчки скидає елементи. Водій робить роботу правильно. Дані не надходять. Водія звинувачують.
Що насправді вимагає офлайн-first
Офлайн-first — це не функція, яку додають. Це властивість архітектури, і або застосунок побудований навколо неї з першого дня, або ні.
Форма, яка працює:
Локальне сховище є джерелом правди для сесії. Коли водій сканує пакет, скан записується в надійне локальне сховище негайно, і UI читає з нього. Серверна синхронізація — окремий процес, що запускається, коли може. UI не чекає сервера; він показує локальний стан, який і є реальним станом, що водій бачить.
Кожна дія має ID, згенерований на стороні клієнта. UUID-и, згенеровані на пристрої до виконання дії. Це означає, що ту ж дію можна безпечно повторювати нескінченно без створення дублікатів на сервері, і дія існує в локальному сховищі зі стабільним ідентифікатором навіть до того, як сервер її коли-небудь побачить.
Синхронізація видима користувачеві, а не прихована. Маленький індикатор: "12 дій очікують, остання синхронізація 4 хвилини тому." Водії вважають це заспокійливим. Вони хочуть знати, чи зафіксована їхня робота. Приховування стану синхронізації заради "чистоти UX" — це те, що призводить до сценарію "відсканував, але насправді ні."
Токени автентифікації мають тривалий офлайн-термін. Ввійшли один раз — отримали токен, що витримує кілька діб офлайн. Оновлюйте токен у фоні, коли мережа є. Збій мережі при оновленні токена — нонсенс; лише реально прострочений без оновлення токен повинен примушувати до повторного входу. Ця одна зміна усуває найпоширенішу помилку початку робочого дня.
Що це змінює на серверній стороні
Офлайн-first зазвичай розглядається як клієнтська властивість. Але вона має наслідки й для сервера.
Серверні endpoint-и мають бути ідемпотентними. Клієнт повторюватиме запити. Повтори відбудуться через дні після оригіналу. Оригінал може бути отриманий, а може й ні. Endpoint мусить обробляти "я вже обробив цю дію з цим клієнтським ID" коректно — повертаючи той самий результат, а не створюючи дублікат або відхиляючи запит.
Час на сервері — це не той самий час, що на клієнті. Дія виконана о 9:14 за місцевим часом водія, але сервер фіксує її о 11:47 після повернення водія до зони покриття. Кожен запис потребує обох міток часу. Звіти, що їх плутають, вводитимуть бізнес в оману.
Структура даних має допускати врешті-узгоджені правки. Водій може позначити пакет доставленим, а потім супервайзер може позначити його як повернення — до того, як дія водія синхронізується. Вирішення конфліктів має бути навмисним, а не "перемагає останній запис за випадковістю." Зазвичай правило таке: "дія водія має пріоритет у межах зміни, дія супервайзера — після зміни", але це залежить від бізнесу.
Практичний тест
Якщо ви оцінюєте логістичну платформу — купуєте чи будуєте — спочатку запустіть тест ліфта. Візьміть застосунок, телефон, закрийте двері ліфта, виконайте звичайне завдання. Подивіться, що відбудеться.
Платформи, що проходять цей тест, зазвичай в нормі. Ті, що провалюються — провалюватимуться у виробництві щодня і звинувачуватимуть мережу, коли це станеться.
Хочемо почути ваші думки.
наш CTO Кирило Осадчук відповість протягом 24 годин. Без воронки продажів.
Start a conversation
We want to hear your thoughts
Re: Ваш застосунок для водіїв має працювати в клітці Фарадея