Это история о том, как простой побочный проект может легко развиваться, как принимать иррациональные решения и как получать от этого удовольствие!
Идея
У меня уже много лет есть Raspberry Pi с экраном 5, и он просто пылится у меня на полке. Но на прошлых выходных у меня возникла отличная идея, как это использовать. Гипотеза была такой:
В компании, с которой я работаю, мы запускаем платформу с десятком микросервисов. Эти программы отвечают за всю обработку. Для меня было бы полезно всегда видеть состояние каждой из этих программ, чтобы в случае сбоя одной из них я мог немедленно отреагировать.
Это не должно быть слишком сложно, правда? Платформа использует Kubernetes, поэтому получить доступ к данным довольно легко (с помощью kubectl), и они будут хорошо отображаться на экране. Будет здорово!
Прототип
Моя миссия была достаточно простой - отображать на экране данные по наиболее важным микросервисам. Эти данные включают: как долго служба работает, сколько раз она перезапускалась и работает ли она в данный момент.
Процесс настройки был прост:
- Скачайте Raspbian OS (голая версия, потому что кому нужен рабочий стол)
- Установите его на карту MicroSD
- Настроить все на Raspberry (WiFi, ssh, драйверы экрана, kubectl)
- Настройте простую однострочную команду bash, которая будет обновлять данные каждую секунду.
- Заставить его запускаться при запуске
По сути, kubectl - это команда, с помощью которой я могу получать последние данные, WiFi позволяет Raspberry общаться с внешним миром, ssh позволяет мне разговаривать с Raspberry, а драйверы экрана позволяют мне действительно видеть вещи на экране.
А команда? На самом деле довольно просто:
watch -n 1 kubectl get pods | grep "sandbox\|memc\|mongo\|postgres"
Вот что я получил в результате:
Затраченное время: 1,5 часа
Но подождите, есть проблема ... Я чувствовал, что это было очень просто. Я просто не чувствовал удовлетворения от тяжелого рабочего дня. Я знаю, позвольте мне добавить еще кое-что!
Вглубь через кроличью нору
Позвольте мне просто закодировать каким-нибудь цветом. Это будет значить для меня мир в будущем. Кроме того, я в будущем определенно захочу, чтобы логику раскраски можно было легко программировать, чтобы она могла поддерживать всю сложную логику, которая обязательно понадобится.
Для этого я решил перейти от Bash к Python. Вот где я рок, и это будет сделано в кратчайшие сроки. Я решил всего лишь с одним небольшим ограничением - программа могла использовать только стандартные библиотеки Python, так как в противном случае это сильно упростило бы задачу, и я хотел узнать что-то новое.
Так и было. Имея 2 класса, 1 рекурсивную и 5 обычных функций, всего 127 строк кода, у меня было собственное решение для мониторинга с цветовой кодировкой. Глядя на него на своем 15-дюймовом ноутбуке с процессором i7, 16 ГБ ОЗУ и видеокартой Nvidia, я подумал про себя: Это то, чем я мог бы гордиться.
… Пока я не запустил его на Raspberry. Там я мог видеть сбои каждый раз, когда экран обновлялся. Он не мог очистить весь экран и перепечатать все достаточно быстро. Он был настолько медленным, что обновление происходило каждые 3 секунды вместо 1 секунды, которую я запрограммировал. Кроме того, некоторые цвета затрудняли чтение данных. Довольно обидно.
Затраченное время: 3 часа
Хорошо, хорошо, без проблем. Мне просто нужно немного оптимизировать код. Необязательно обновлять каждую секунду, но мне нужно избавиться от сбоя.
Я имел в виду пару оптимизаций - каждый раз, когда я получаю новые данные, я сравниваю их со старыми. Если то же самое, я просто проигнорирую это, потому что это означает, что ничего не изменилось. Также я буду хранить все, что нужно распечатать, чтобы при печати я распечатал все сразу.
После того, как я закодировал изменения, я был счастлив! У меня наконец-то был рабочий день, который приносил мне такое удовлетворение. Жаль, что глюки никуда не делись.
Делай или не делай, нет попытки
Это не могло победить меня. Я знал, что решение состоит в том, чтобы найти способ перепечатать только измененные данные. После большого количества исследований (StackOverflow) я обнаружил, что моим единственным решением была эта библиотека curses, которая позволяла мне редактировать каждую строку и столбец, отображаемые отдельно.
Это означало, что мне пришлось переписать весь процесс печати. Я закончил тем, что сопоставил положение каждой части информации на экране, искал изменения в этой информации и затем заменил ее соответствующим образом.
Это принесло много боли (и удовольствия?). Если я хотел напечатать новую информацию поверх старой, мне приходилось сравнивать строки, и в случае, если новая была короче, мне приходилось добавлять пробелы, чтобы перезаписать разницу. Когда служба завершалась, она должна была исчезнуть с экрана, а это означало, что мне пришлось очистить эту строку, а затем сдвинуть все остальные строки вверх, чтобы закрыть пустое пространство. Мне также приходилось следить за тем, как цвет линии меняется в зависимости от изменений данных, потому что всю строку нужно было перепечатывать.
Многие из этих мелочей складывались бы, и в итоге я получал 236 строк кода, и я тратил почти весь день на программирование. И даже сейчас я все еще не закончил, из-за маленького размера экрана мне нужно внести некоторые изменения, чтобы все было правильно отрисовано.
Подумать только, что у меня была почти такая же функциональность с этой одной строкой кода Bash. Я был сумасшедшим?
Стоило ли?
да. И нет.
Мне было очень весело программировать и решать эти проблемы, смешанные с некоторыми разочарованиями, которые обычно возникают в этом направлении бизнеса. И это то, что, я думаю, часто теряется, когда вы начинаете зарабатывать на жизнь программированием, потому что мы зацикливаемся на спецификациях и сроках. Я также многому научился - как управлять экраном на уровне персонажа, что часто имеет смысл думать об аппаратных ограничениях и как сделать так, чтобы Raspberry выглядела круто.
С другой стороны, конечный результат не намного лучше, чем то, с чего я начал в Bash, и даже сейчас мне все еще нужно внести некоторые изменения. Так что, возможно, я мог бы использовать это время для чего-то другого и нарушить свой стандартный распорядок дня.
Что меня интересовало, так это (не очень) тонкие иррациональные решения, которые я принял в этом проекте. Так что учитесь на моем опыте. Не обязательно, как стать менее иррациональным, но как распознать такое поведение и учесть его в процессе принятия решений. Кроме того, экспериментируйте и получайте удовольствие - это самое главное :)
Затраченное время: 8 часов
Что вы думаете?
Я действительно хочу знать, что вы думаете. Вы знаете, как лучше решить проблемы, с которыми я столкнулся? Вы нашли это полезным и хотели бы, чтобы я опубликовал код на GitHub?