(no subject)
Aug. 1st, 2017 06:00 pmУроки, які я виніс із свого скриптописання для важливих речей в умовах Дикого Заходу Перла, відсутності тестів і типів, і чого мені тепер у чужих скриптах часто не вистачає:
Ще у мене за час епопеї із міграцією готелів із однієї системи полісі на іншу (точніше, прикривання старої системи новою) виробився досить корисний протокол щодо важливих змін:
Отак і живем, хоча відсутність статичних гарантій і часто банального розуміння коду без запуску це ніби відсутність елементарної гігієни. Але все-таки цікаво, що інженерна культура не вичерпується статичними гарантіями і навіть на такому безриб'ї можна чомусь навчитись.
- логувати багато і всеохопно (коли від скрипта залежить залежать суми в десятки річних зарплат, кожний можливий шматок даних може стати критичним, якщо щось піде не так);
- логувати в формі, відносно легкій для аналізу звичними інструментами, в моєму випадку пласкі файли, які можна обробляти юніксовими утилітами; не забувати час та контекст, важливість запису; треба шукати компроміс між легкістю людського сприйняття (skimability: наскільки його можна переглядати по діагоналі) і можливістю парсити пізніше;
- логування також часто є формою документації та коментування коду: для розуміння перлівського коду його треба запускати і дивитись, що він робить, а логування це і є спосіб дивитись це.
- логувати весь control flow: щоб за логом завжди можна було відтворити виконання;
- ловити і детально логувати помилки; помилки не можна мовчки ігнорувати;
- урок, натхнений Хаскелем: робити режим --dryrun, коли скрипт збирає всі дані і робить все, що повинен, за винятком критичних ефектів типу запису в бази даних: багато помилок ловиться під час dryrun і це іноді корисний інструмент для збору інформації про те, що хочеш зробити. Крім того, це незамінний інструмент для розуміння чужих скриптів, які часто неясно навіть як запустити.
Ще у мене за час епопеї із міграцією готелів із однієї системи полісі на іншу (точніше, прикривання старої системи новою) виробився досить корисний протокол щодо важливих змін:
- спочатку тестувати у розробницькому середовищі (у нас є розробницьке середовище, із повними копіями усіх баз, які робляться щоночі);
- старатись відділяти дані від дій: збір даних і прийняття рішень, що робити, має бути відділене від самих дій; проміжні дані/рішення мають зберігатись і не повинні бути ефемерними; краще написати скрипт, який збирає дані і приймає рішення, і окремий скрипт, який реально виконує рішення першого скрипта, щоб проміжні дані збереглись;
- часто хороша ідея робити скрипти reversible, щоб можна було все відкотити назад, але тут неминучі деякі компроміси;
- щедро додати асерти та перевірки припущень і preconditions;
- тестувати на продакшні із dryrun, перевірити логи на помилки і будь-які аномалії;
- тестувати якусь реальну вибірку методом Монте-Карло: брати випадкову вибірку, вручну ретельно перевіряєш результати
- не робити великі зміни (кілька тисяч готелів) за один раз, бити на менші batches і пробувати щось робити поступово і ітеративно, щоб можлива шкода була більш обмежена і помилки встигали виявитись; нарощувати батчі експоненційно, якщо є можливість;
- вести детальний відтворюваний журнал ручних дій із часом кожної дії;
- виділяти час на аналіз результатів і бути готовим до firefighting після виконання скрипта, не робити такі зміни ввечері, перед вихідними і перед відпустками.
Отак і живем, хоча відсутність статичних гарантій і часто банального розуміння коду без запуску це ніби відсутність елементарної гігієни. Але все-таки цікаво, що інженерна культура не вичерпується статичними гарантіями і навіть на такому безриб'ї можна чомусь навчитись.
(no subject)
Date: 2017-08-01 06:07 pm (UTC)Потім ще доведеться логувати так, щоб можна було масштабувати збір даних - splunk, тощо.