Блог ·
Індикатор, який відмовляється вгадувати
Більшість оцінок часу вигадані. Ось правило, яке вирішує, коли панель має право показати оцінку, і що вона пише на екрані, коли такого права немає.
Автор: Provibr
Хтось натискає кнопку встановлення. Машину треба клонувати, завантажити, налаштувати й перевірити, і десь посеред цього клієнт хоче знати одну річ: скільки це триватиме.
Легка відповідь це зворотний відлік. Узяти правдоподібне число, віднімати щосекунди одну секунду, і екран має вигляд такого, що щось знає. Він не знає. Зворотний відлік є обіцянкою про момент, а того моменту не знає ніхто в цій будівлі.
Тож ми записали правило, дали йому номер версії й змусили панель казати вголос, коли вона під нього не підпадає.
Правило, коротко
Оцінка часу зʼявляється лише тоді, коли справджуються обидві умови. Має бути щонайменше двадцять успішних запусків такої самої роботи за останні тридцять днів, і розкид має бути щільним: девʼяностий перцентиль не може перевищувати медіану більш ніж у два з половиною раза. Якщо не виконано хоч одну з умов, екран показує етап, витрачений час і речення про те, що оцінки немає.
Ці три числа живуть в одній константі з полем версії поруч, і більше ніщо в кодовій базі не має права мати про них власну думку.
| Ситуація | Що показує екран |
|---|---|
| Менш ніж двадцять порівнянних запусків за тридцять днів | «No reliable time estimate yet» (надійної оцінки часу ще немає), разом із тим, скільки запусків записано і скільки потрібно |
| Двадцять або більше за тридцять днів, але розкид завеликий | «No reliable time estimate», і що запуски були надто розкидані |
| Обидві умови виконано | «Comparable tasks took X to Y minutes, based on N runs in the last 30 days» (порівнянні завдання тривали від X до Y хвилин, за N запусками за останні 30 днів) |
Прочитайте третій рядок уважно. Це діапазон, і він називає власний доказ. Це не смуга, що повзе до фінішної лінії, і вона ніколи не перетворюється на «залишилося 3 хвилини».
Чому діапазон, а не зворотний відлік
Зворотний відлік поєднує дві помилки. Він ховає невизначеність і щосекунди стверджує себе наново, тож у хибності зʼявляється ритм. Кожен бачив, як діалог копіювання обіцяє чотири хвилини, потім чотирнадцять, потім дві, і секунд за тридцять навчився, що те число нічого не означає. Щойно читач цього навчився, кожне інше число на екрані коштує трохи менше. Діапазон, названий один раз разом із кількістю спостережень, так зробити не може.
Умова про розкид є тією частиною, яка виконує справжню роботу. Двадцять спостережень із медіаною чотири хвилини й девʼяностим перцентилем сорок хвилин це не когорта, у якій є прогноз; це дві різні популяції під одним ярликом, а їхнє усереднення дає число з десятковою комою й без сенсу. Два з половиною є обраним числом, а не виведеним, і поле версії існує для того, щоб зміна цього числа згодом була видимим рішенням.
Когортою є ваш власний акаунт, і це свідомо
Очевидний спосіб швидко набрати двадцять спостережень це міряти по всій платформі. Ми так не робимо. Когортою є вид роботи в межах однієї організації.
Причини дві, і вирішила друга.
Перша це порівнюваність. Ваша власна історія є найсхожішою популяцією з наявних: той самий гіпервізор, та сама мережа, ті самі образи, те саме сховище.
Друга полягає в тому, що кількість спостережень стоїть на екрані. Речення, яке називає, скільки порівнянних запусків платформа побачила за тридцять днів, є твердженням про наш власний обсяг, надрукованим у панелі клієнта, і його віддали б в обмін на трохи кращу оцінку. Обмеження запиту однією організацією означає, що число на вашому екрані є фактом про вас.
Практичний наслідок полягає в тому, що молодий акаунт певний час не бачить жодної оцінки, і це є правильною поведінкою, а не прогалиною, яку треба заповнити. Не показувати нічого краще, ніж показувати число, яке нічого не означає.
Таблиці спостережень не існує
Тривалість успішного завдання є різницею між двома мітками часу, які вже зберігаються на самому завданні. Окремої таблиці вимірювань немає.
Це звучить як очевидна економія, і варто сказати, чому це було рішенням. Друга таблиця тримала б ту саму правду двічі, і вони розійшлися б першого ж разу, коли підмітання ретенції торкнеться однієї й не торкнеться другої. Єдине, що вона справді додала б, це спостереження, які переживають завдання, з яких походять, а це має значення лише тоді, коли період зберігання коротший за вікно вимірювання. Сьогодні зберігання становить девʼяносто днів, а вікно тридцять, тож питання не виникає.
Одна виноска, яка цю кодову базу вже кусала: запит перцентиля повертає double, а лічильник повертає bigint, який драйвер віддає рядком. Обидва потребують перетворення, і забути рівно одне з двох означає впасти тихо, а не гучно.
Етапи, бо відсоток має звідкись братися
Кожен вид завдання несе впорядкований список етапів. Встановлення проходить: у черзі, підготовка, завантаження, встановлення, завершення. Звантаження з URL проходить: у черзі, надіслано агентові, звантаження, перевірка, застосування. Відсоток виводиться з позиції в тому списку, якщо тільки сама робота не звітує власний справжній відсоток, і тоді перемагає він.
Це перевизначення важить більше, ніж здається. Встановлення звітує власну цифру поступу, і вона показується на власній сторінці того сервера; якби висувна панель обчислювала друге число з позицій етапів, один екран ніс би два різні відсотки про ту саму роботу. Це друга копія правди, на шар вище.
Переклад із фаз встановлення в етапи лежить рівно в одному місці, записаний як вичерпний запис, а не як оператор switch. Чотирнадцять фаз із двох різних драбин встановлення відображаються на пʼять етапів, які клієнт упізнає. Нова фаза є помилкою компіляції, а не етапом, що тихо провалюється в перший.
Застаріле не означає невдале
Порогів на свіжість останнього звіту про поступ два: дві хвилини й десять хвилин. За першим екран каже, що оновлень не було від зазначеного часу. За другим він каже, що відтоді нічого не звітувалося.
Жоден із них не змінює статус. Робота може виконуватися бездоганно. Спинилося звітування, і читач заслуговує, щоб йому це сказали, а не щоб він дивився на смугу, яка не рухається, і робив власні висновки. Ототожнювати мовчання з невдачею це та сама помилка, що й закрити інцидент, бо перестали надходити вимірювання, і ці два слова варто тримати окремо скрізь, де вони зʼявляються.
Висувна панель не володіє нічим
Висувна панель фонових завдань у шапці сидить поверх усього цього, і правило її проєктування коротке: вона не тримає власного стану про роботу. Єдиний шматок локального стану в тому компоненті це те, чи панель відкрита. Немає циклу запитів, немає інтервалу, немає другого сокета. Початковий стан приходить із того самого запиту, який використовує сторінка деталей, а живі оновлення приходять зі спільного сховища реального часу.
Тест читає синтаксичне дерево компонента й падає, якщо якийсь локальний стан колись триматиме статус, етап чи відсоток. Це сильніша гарантія, ніж рецензія коду, з тієї самої причини, з якої коментар не є тестом.
Одну деталь там легко зрозуміти навпаки: групи у висувній панелі обчислюються після застосування живої латки, а не до неї. Обчисліть їх спершу, і завдання, яке щойно впало, залишиться сидіти в групі виконуваних до наступного повного завантаження сторінки, тихо показуючи спінер поруч із тим, що вже червоне.
Три дефекти, які знайшла лише перевірка
Усі три компілювалися, проходили перевірку типів і юніт-тести.
Квитанція ніде не записувалася. Код посилався на функцію, якої не існувало, тож успішне встановлення давало завдання з розділом результату, що назавжди залишався порожнім.
Нерозпізнана фаза встановлення стирала записаний етап у порожнечу. Відображення правильно не повертає нічого для фази, якої не знає, але той, хто його викликав, записував те ніщо в рядок, тож старіший агент, який звітує перейменовану фазу, стер би етап завдання, що виконувалося нормально. Виправлення це один відкат до етапу, який там уже був, і запобіжник довели червоним, перш ніж йому довіряти.
Завершене завдання й далі крутилося. Етапом завершеного завдання є все ще останній етап, якого воно досягло, і це правильно, бо інакше не було б видно, де воно скінчилося. Помилка полягала в тому, що питання «чи є цей етап поточним» ставили порівнянням назв, тоді як справжнє питання це те, чи завдання ще активне. Невдале завдання так само не отримує зеленої галочки на етапі, на якому померло: той етап було покинуто, а не завершено, тож він має власний стан замість того, щоб бути підшитим до зробленого чи до нерозпочатого, бо і те, і те стверджувало б неправду.
Що ми б записали
- Покладіть правило оцінки в одну версійовану константу. Питання «чи була захищуваною оцінка, яку ви показували в березні» має відповідь лише тоді, коли відомо, яке правило тоді діяло.
- Зробіть відсутність оцінки реченням, а не порожнім місцем. Порожнеча там, де мало бути число, читається як помилка; «No reliable time estimate yet. 6 of 20 comparable runs recorded.» (надійної оцінки часу ще немає, записано 6 з 20 порівнянних запусків) читається як система, яка знає, чого вона не знає.
- Обмежте когорту клієнтом і прийміть, що нові акаунти певний час не бачать нічого. Альтернатива друкує на їхньому екрані ваш власний обсяг.
- Ніколи не дозволяйте висувній панелі, значку чи віджету тримати власну копію статусу. Два числа про одну роботу на одному екрані гірші, ніж жодного числа.
- Відокремте мовчання від невдачі у словнику, у моделі даних і на екрані, і тримайте їх окремо всюди.
Чесні межі: цей шар працює сьогодні для чотирьох видів роботи, і список навмисно короткий, бо вид, якого ніхто не може запустити, є категорією, що рендериться порожньою. Потік скасування може записати запит, але жоден виконавчий шар його поки не підтверджує, а висувна панель не має точки входу нижче 768 пікселів ширини екрана.
Той самий аргумент, застосований до речі, до якої зазвичай прикріплений індикатор поступу, є в чому 200 від Proxmox не є результатом, а причина, з якої ми перестали довіряти власним дедлайнам, є в тайм-аут не є кнопкою зупинки.
З роботи над платформою Provibr.