• Коронавирус на Титанике

    Несколько лет назад мы с сыном увлекались Титаником. Посмотрели несколько документальных фильмов, читали Википедию. Помнится, в 2012 году была столетняя годовщина со дня трагедии, и под это дело Титаник всплыл в информационном поле.

    Изучая историю Титаника, поражаешься нелепым промахам и неудачам. По сути вся история — это череда ошибок. Титаник был приговорен еще в момент спуска на воду, да что там — на этапе чертежей. Проплыви он тот рейс, проблема возникла бы в следующий. Через десять рейсов или сто, неважно. Точно так же была бы трагедия и тысяча с лишним погибших.

    В спорах о Титанике даже речи не может быть о том, какую именно ошибку допустил экипаж. Их было столь много, что можно спорить только о вкладе в общую картину, но никак не о бинарном признаке “было/не было”.

    Прямо сейчас, не заглядывая ни в какие интернеты, перечисляю ошибки по памяти. Для удобства делю причины на группы.

    Устройство

    • Дрянные заклепки корпуса, которые лопнули при столкновении.
    • Система сообщающихся отсеков. Заполнив один отсек, вода спокойно переливалась в следующий и так далее.
    • Недостаточное число шлюпок и мест в них: 1200 мест на 2600 пассажиров.

    Халатность

    • Только один бинокль на смотровой площадке. При смене вахты смотрящий забыл передать ключ от сейфа с биноклем второму смотрящему, а тот поленился идти за ним.
    • На борту были только белые сигнальные огни, которые означают внимание. Судно браконьеров было рядом, но там белые огни приняли за фейерверк и поспешили уплыть. Красных огней, означающих бедствие, не было.

    Действия экипажа

    • Первые двадцать минут после столкновения судно шло на полном ходу, из-за чего напор воды из пробоины усилился в десять раз.
    • Долгое время никто ничего не понимал, считали, что все хорошо.
    • Решение опустить перегородки в отсека было фатальным. Если бы вода равномерно растекалась по корпусу, судно погружалось бы в течение 15 часов. За это время пришла бы помощь. Из-за того, что отсеки заполнялись по одному, судно накренилось и переломилось спустя три часа после столкновения.
    • Радисты посылали старый сигнал CQD, хотя все уже перешли на SOS.
    • Экипаж не умел спускать шлюпки, учения никогда не проводились. Где-то их спускали наполовину пустыми, на голову другим или переворачивали.

    Список можно растянуть на два-три экрана. Не будем этого делать, потому что и так ясно: с самого начала все пошло не так, и кончиться иначе не могло. Сегодня, когда мы смотрим фильм про Титаник или читаем википедию, в голове одна мысль: как так? Почему провафлили все что можно? Почему обделались буквально на каждом шаге? Разве нельзя было подумать заранее?

    Всю эту петрушку про Титаник я написал потому, что вижу явное, стопроцентное совпадение с короновирусом. Как и сто лет назад, человечество целиком обосралось. Уверен, в будущем события наших дней будут разбирать с тем же чувством сочувствия и снисхождения. Видите, что устроили эти болезные. Что ж, пожалеем их, вздохнем и пообещаем так не делать.

    В борьбе с коронавирусом мы, как и отчаянный экипаж идущего на дно судна, сделали неправильно буквально все. В защиту экипажа можно сказать, что у них было не более часа на обдумывание ситуации. А у нас ковидная вакханалия длится уже полтора года, но просвета чиновничей глупости не видно.

    Отмотаем время на год назад. Помните ковидные локдауны по три месяца? Stay Home? Ролики с селебрити, где на все лады повторяли эту фразу? Очевидно, это не сработало. Стоило людям выйти на улицу, настала т.н. “вторая волна”. Беру в кавычки, потому что именно под этим термином нам ее подавали. На самом деле это была первая волна, которую просто искусственно прервали. Да и вообще, нет никаких волн — есть локальные вспышки, есть сезонность. А волны только в Доте.

    Сиденье в закрытых помещениях на столь долгий срок привело к тому, что многие потеряли работу. Как удаленно работать учителю музыки, официанту, гардеробщику? Принимать шубу по скайпу? В считанные месяцы население обеднело и, как результат, стало хуже питаться. Повысились стресс и домашнее насилие. В закрытых помещениях без свежего воздуха теряется иммунитет.

    На людей обрушилась невероятная по своей мощи информационная волна. Новости, ежедневные сводки, ток-шоу, эксперты. Вирус несется из каждого утюга. Сраная Медуза показывает в шапке график заболеваемости, словно это курс доллара. Манипуляции с цифрами и статистикой. На ковид списывают ножевые ранения и несчастные случаи. Врачам доплачивают за ковид.

    Подтягиваются политики и чиновники. Настал их час: всем хочется порулить в момент кризиса, чтобы стать героем. Ввели пропуска, отменили пропуска. Вчера победили ковид, а завтра ВНЕЗАПНАЯ третья (четвертая, пятая) волна. Еще лучше: новый штамм (бета, гамма, сигма — греческих букв хватит надолго).

    Ввели QR-коды, отменили QR-коды. Ввели мобильное приложение, отменили мобильное приложение. Попутно выставив миллионы штрафов просто за то, что люди не осилили адский интерфейс.

    Все ситуативно, непредсказуемо. Сыпятся ограничения, при этом нет режима ЧП. Нет никакого плана или стратегии хотя бы на месяц. Все решается в полете.

    Каждый день в новостях высказывания одно тупей другого. Вылазят обласканные политикой врачи. Те, кто не хочет привиться — биотеррористы. Дополню: приравнять к зомби и выдать лицензию на отстрел.

    Потребление наркотиков возросло на 60%. Неудивительно: как иначе людям справляться с накатившим стрессом?

    Начинается война вакцин и сегрегация. В условную Францию нельзя, потому что не привит. Или привит, но не тем. Сраная Европа не одобряет вакцину России. Сраная Россия не одобряет европейскую. Думай о том, чем привиться выгодней, чтобы охватить больше стран. Чиновники массово едут в Европу и колят Файзер, который простому смертному не достать.

    Во всем этом нет ни грамма заботы о людях. От начала до конца все основано на невежестве и жадности. Короновирус — исключительно политический момент. Он стал поводом, чтобы проталкивать внешние и внутренние решения. Внешние — в плане вакцин, чтобы застолбить свой стандарт. Тот, чья вакцина выиграет, будет подтираться золотой бумагой. Внутренние — для давления на население. Митинги нельзя, больше двух не собираться, не уколешься — не получишь зарплату.

    Коронавирус — это война человечества с самим собой. В отличии от старых войн, теперь не нужно сбрасывать бомбы и давить танками крестьян. Враг безлик, его нельзя найти в горах и уничтожить. Очень удобно.

    Помнится, Барак Обама возвещал, что Россия и вирус Эбола представляют главную угрозу человечеству. С Эболой не сложилось, но уже тогда было видно, насколько желанна эпидемия мирового масштаба.

    Ладно, что же надо делать?

    Во-первых, определиться с терминами. Что такое эпидемия и пандемия? При каких порогах можно утверждать, что в стране происходит второе или первое? Когда определения и пороги найдены, составить план и следовать ему, при этом оперативно уведомлять население о том, где мы и куда движемся. Ничего подобного я не вижу в принципе. Если включить новости Москвы, то все будет плохо, при этом чрезвычайного положения нет, все оперативно и на ходу.

    Наиболее разумный шаг — оставить население в покое. От недостатка денег и стресса умирает гораздо больше людей, чем от коронавируса. Загуглите графики избыточной смертности в Москве и в Питере. Странным образом вместе с ковидниками умирает много других людей. Это те, кто в результате беспощадной борьбы не смог получить помощь: сердечники, раковые больные, инвалиды с редкими болезнями.

    Не вводить поголовную вакцинацию. Вакцина нужна ослабленным людям, пожилым и тем, кто в группе риска. Остальным — повышать иммунитет, качество воды, продуктов питания и жизни в целом. Поощрять проветривания и зарядку.

    Уж давно выяснили, что вирус боится именно проветривания, а не социальной дистанции в полтора метра. Но по-прежнему многие помещения задраены, окна закрыты, а тебя просят “одеть масочку”. Заодно вскрылась бездна людей, не способных отличить “одеть” от “надеть”.

    Наконец, за полтора года можно было вывести из комы массовую медицинскую помощь. Выясняется, что в 18 году число койко-мест “оптимизировали” до 40%. И не только у нас. В Америке программа Obama Care точно так же похоронила массовую медицинскую помощь. Смысл программы в том, чтобы обязать гражданина купить медстраховку. А на что ее купить, если сидишь дома или потерял работу? Или работаешь неофициально? В ответ программа несет чушь про гибкую систему скидок.

    Государства, что наше, что иностранные, полностью снимают с себя ответственность за здоровье гражданина. В результате Америка угробила население, обогатив кошельки страховых компаний. Россия ничуть не лучше: деньги от “оптимизации” медицины пошли явно не на медицину.

    Еще раз: в полуторагодовой борьбе с вирусом нет ни грамма заботы о людях. Ни одна страна не ставит цель иметь здоровое население, где локальные вспышки гасит массовая бесплатная медицинская помощь. Ковид — два в одном, повод и инструмент. Это политика, деньги и война вакцин. Печально наблюдать эту картину Босха в мировом масштабе, и тем труднее сохранить остатки критики и разума.

  • Ссылки на выходные (выпуск 35)

    Давно не писал в блог. Все свободное время трачу на большую главу по базам данных в Кложе. На какой-то период ограничимся ссылками на выходные.

    Этот выпуск посвящаю Леониду Каганову.

    • Фантастический рассказ “Мне повезет”

      Занятный рассказ, и смешно и грустно одновременно. Займет двадцать минут, не пожалеете.

    • Поговорим про умный дом?

      Давно хотел написать о том, какая чушь все эти умные дома. Но Леонид сделал это раньше и лучше.

  • Crontab и отправка почты

    На днях столкнулся с проблемой. На моем ноуте крутится несколько crontab-задач. Хотелось бы видеть, когда сработала каждая из них и если нет, то почему. Какое-то время я выкручивался с помощью логов. Оба канала (stdout и stderr) перехватываются в общий пайп, где каждая строка предваряется текущий датой и записывается в файл. Например:

    SHELL=/bin/bash
    
    0 */3 * * * /path/to/command &> >( while read line; do echo "$(date): ${line}"; done >> /Users/ivan/logs/command.log)
    

    В результате и обычный, и ошибочный выхлоп оседают в файле. Выглядит это так:

    Tue Jun 22 15:58:02 MSK 2021: warning: Skipping file ...
    Tue Jun 22 15:58:19 MSK 2021: Completed 0 file(s) with ...
    Tue Jun 22 15:59:02 MSK 2021: warning: Skipping file /Users/ivan/...
    Tue Jun 22 15:59:19 MSK 2021: Completed 0 file(s) with ...
    

    Недостаток в том, что логи нужно регулярно проверять. Об этом легко забыть на месяц, а потом выяснится, что задача не работала из-за глупой ошибки.

    Тут я вспомнил, что крон умеет отправлять выхлоп задачи на почту. Если задана переменная MAILTO=<email>, то на эту почту свалится выхлоп. Это значит, отпадают логи, ведь теперь достаточно проверить почту. Проверять ее можно и с телефона, что в разы удобней.

    Отправка письма работает за счет утилиты mail. В общем виде ей пользуются так:

    cat something | mail -s 'subject' friend@domain.com
    

    Эта команда отправит письмо на сервер domain.com, при этом отправитель будет выглядеть как ivan@ivan.local, то есть имя пользователя и текущего хоста. То же самое можно получить командой:

    echo `whoami`@`hostname`
    

    Обратите внимание на кавычки – они означают выполнить выражение в новом шелле и подставить результат.

    Отправленное письмо никто не получит, что потому что современные сервера отметают письма, где айпи отправителя не совпадает с айпи его домена. Это хорошо, иначе бы мы утонули в спаме. Будем отправлять письма с серверов Гугла. А чтобы mail мог подключиться к Гуглу, сделаем три вещи.

    Первое. В файл /etc/postfix/main.cf дописать строки ниже. Делать это нужно под sudo:

    relayhost = [smtp.gmail.com]:587
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    smtp_sasl_security_options = noanonymous
    smtp_use_tls = yes
    smtp_sasl_mechanism_filter = plain
    

    Второе. Создать файл /etc/postfix/sasl_passwd и вписать в него:

    [smtp.gmail.com]:587 username@gmail.com:password
    

    , где password — пароль приложения для почты. Сгенерить этот пароль можно на специальной странице Гугла.

    Замечу, что вместо gmail.com может быть ваш домен, если он нацелен на гугловые сервера как в моем случае.

    Третье — указать postfix новые конфиги и перезагрузить его:

    sudo chmod 600 /etc/postfix/sasl_passwd
    sudo postmap /etc/postfix/sasl_passwd
    sudo launchctl stop org.postfix.master
    sudo launchctl start org.postfix.master
    

    Все. Пробуем отправить письмо. Сообщим в нем содержимое домашней папки:

    ls -l | mail -s 'my home dir' ivan@grishaev.me
    

    Мне пришло с первого раза. Plain text, красота.

    Так вот, теперь когда почта работает, настроим крон. Открываем его командой crontab -e и пишем сверху:

    MAILTO=<ваша@почта>
    

    Кроме того, в конец каждой команды добавляем эхо, например:

    0 */3 * * * cd /some/path && command --foo 42 && echo OK
    

    Зачем нужно эхо? Оказалось, что крон не отправляет письмо, если выхлоп задачи пуст. А поскольку я всегда хочу знать о запуске задачи, то делаю вывод не пустым. Вместо echo OK можно вывести текущую дату с помощью && date.

    В результате мы получим письмо, где тема — команда задачи, а тело — ее выхлоп. Работает в том числе и для задач, которые не сработали из-за ошибки.

    Я уж не говорю о том, что с помощью mail можно быстро что-то скидывать себе на почту, организовать какие-то заметки и прочее. Что самое прекрасное — нет интерфейса, все простое и открытое, работает везде. Чудо.

    В следующий раз расскажу, что именно я ставлю на крон, там тоже интересные вещи.

  • И ещё немного книг

    Выкладываю ещё несколько прочитанных книжек. Полную подборку см. на книжной полке.

    Чернобыль. История катастрофы
    Хиггинботам Адам

    Полная история чернобыльских событий. Начинается задолго до взрыва, охватывает становление Припяти и ранние опыты с атомной энергией в СССР. Подробно описаны причины, которые привели к взрыву, в том числе организационные. Центральные персонажи показаны правдиво и без тех прикрас, что были в сериале HBO. Книга заканчивается развалом СССР и эпилогом. Рекомендую к прочтению.

    Digital минимализм. Как навести порядок в цифровой среде
    Рыжина Анастасия

    Книга о том, как навести порядок в файлах: на локальном компе и в облачных хранилищах. Довольно занятно, но затянуто. Проблема в том, что материал тянет на хорошую статью, но никак не на книгу. Отсюда дешёвые способы выйти на объём: мудрые цитаты на разворот, письма читателей и прочий балласт. Но пробежаться стоит.

    Думай как математик. Как решать любые задачи быстрее и эффективнее
    Барбара Оакли

    Автор — женщина-учёный, служила в армии США, преподавала в университете. В книге она описывает приемы эффективного обучения. Например, заниматься понемногу, но регулярно; не подчеркивать в книгах; мысленно пересказывать материал. Полезно, но затянуто. Я бы сократил книгу на треть.

    Структуры данных и алгоритмы в Java Лафоре Роберт
    Лафоре Роберт

    Прекрасная книга об алгоритмах. Столь понятного изложения я уже давно не встречал. Все алгоритмы показаны картинками и схемами; к каждому прилагается программа с интерфейсом для визуализации. Первая часть книги посвящена сортировке, вторая — деревьям. Все примеры на Java версии 1.3. Пусть это вас не пугает: никаких классов, всё на примитивах и массивах. Горячо рекомендую книгу всем, кто хочет разобраться с коллекциями и алгоритмами.

    Уступите место драме. Как писать интересно даже на скучные темы
    Сарычева Людмила

    Книга о драматургии Люды Сарычевой, соавтора "Пиши, сокращай". Не думайте, что драматургия — это обязательно Шекспир и все умирают. Речь о том, как сделать текст интересней с помощью персонажей и конфликтов, как обострять акценты и чередовать ритм. Прочитал половину: начало интересное и пригодится всем, а дальше уже только для специалистов в теме.

    Ходячий замок
    Джонс Диана Уинн

    Смотрел этот мульт три раза и вот добрался до книги. Ощущения смешанные: сюжеты расходится, характеры персонажей разнятся. Книга местами затянута и её ритм скачет. Я бы сказал, что мультфильм лучше книги, причём не в плане эффектов, а потому что несёт больше чувств. Но прочитать стоит.

    Искусство войны
    Сунь-Цзы

    Тот самый трактат о войне, написанный две с половиной тысячи лет назад. Оригинал довольно короткий, буквально дюжина керамических табличек. Поэтому современные издания напичканы комментариями толкователей всех мастей. Это весьма раздражает: после каждой фразы оригинала следуют пять абзацев комментариев. К самому трактату претензий нет: он точен, ясен, в нём нет лишних деталей, он несет много пищи для размышления. Удивительно, что человек, который занимался войной, так много пишет о милосердии и заботе о людях.

  • Introducing Farseer: the JSON RPC server, the client and utilities

    (This is a copy of the readme file from the repository.)

    Farseer is a set of modules for JSON RPC. It includes a transport-independent handler, Ring HTTP handler, Jetty server, HTTP client, local stub, documentation, and more.

    What and Why is JSON RPC?

    Briefly, JSON RPC is a protocol based on HTTP & JSON. When calling the server, you specify the method (procedure) name and its parameters. The parameters could be either a map or a vector. The server returns a JSON response with the result or error fields. For example:

    Request:

    {"jsonrpc": "2.0", "method": "sum", "params": [1, 2], "id": 3}
    

    Response:

    {"jsonrpc": "2.0", "result": 3, "id": 3}
    

    Pay attention: the protocol depends on neither HTTP method, nor query params, nor HTTP headers and so on. Although looking a bit primitive, this schema eventually appears to be robust, scalable and reliable.

    Read more →

  • Сага о DRY и зависимостях

    Предположим, в вашем проекте два модуля: project.foo и project.bar. В первый из них вы добавили служебную функцию, например поиск элемента по предикату. Через некоторое время то же самое понадобилось во втором модуле. Как вы поступите?

    Варианты:

    1. Вынесу функцию в третий модуль project.utils и подключу его к foo и bar.
    2. Скопирую функцию во второй модуль.

    Конечно, вы и так знаете, что правильный способ — первый. DRY (Don’t Repeat Yourself), не дублируй код. Держи одну точку входа, чтобы в случае ошибки править в одном месте. Копирование — наш враг и все такое. Я тоже тоже так думал раньше, и вот, в тридцать пять лет, поменял мнение.

    Read more →

  • Clojure Zippers

    Part 1. The Basics of Navigation

    In this article, we will discuss zippers in the Clojure language. These are an unusual way to work with collections. Using a zipper, you can traverse a data structure arbitrarily and modify its content as well as search in it. A zipper is a powerful abstraction that pays off over time. However, it is not as straightforward as regular tools and requires training to deal with.

    Let’s talk about a zipper in simple terms. It is a wrapper that offers a variety of data manipulations. Let’s list the main ones:

    • moving vertically: down to children or up to a parent;
    • moving horizontally: left or right among children;
    • traversal of the entire data structure;
    • adding, editing and deleting nodes.

    Read more →

  • Ссылки на выходные (выпуск 34)

    Советую посвятить выходные новому изданию “Кинжал”. Ребята пишут небольшие заметки о работе и жизни. Получается супер. Каждая заметка — острая и хлесткая, как настоящий кинжал. Никакой воды, только по сути. Эти вещи вы читали у других и у меня, но в “Кинжале” написано лучше.

    То, что зацепило:

    И так далее, на сайте еще.

    А вот Максим Ильяхов (он там редачит) рассказывает об издании.

  • Configuration in Clojure

    Clojure in Production

    In This Chapter

    Configuration

    In this chapter, we will discuss how to make a Clojure project easy to configure. We’ll take a look at the basics of config: file formats, environment variables, libraries, and their pros and cons.

    Formulation of the Problem

    In materials on Clojure, there are such examples:

    (def server
      (jetty/run-jetty app {:port 8080}))
    
    (def db {:dbtype   "postgres"
             :dbname   "test"
             :user     "ivan"
             :password "test"})
    

    These are the server on port 8080 and the parameters for connecting to the database. The examples are useful because you can execute them in the REPL and check their result: open a page in a browser or perform a SQL query.

    In practice, we should write code so that it does not carry concrete numbers and strings. Explicitly setting a port number to a server is considered bad practice. That is fine for documentation and examples, but not for the production launch.

    Port 8080 and other combinations of zeros and eights are popular with programmers. There is a good chance that the port is occupied by another server. This happens when instead of running one service, you start a bunch of them at once during development or testing.

    The code written by a programmer goes through several stages. These stages may differ between companies, but in general, they are development, testing, staging/pre-production, and production.

    At each stage, the application runs alongside other projects. The assumption that port 8080 is free anytime is fanciful. In developer slang, the situation is called “hardcode” or “nailed down.” If there are nailed-down values in the code, they introduce problems into its life cycle. You cannot run two projects in parallel which declare port 8080 in their code.

    The application does not need to know the server port – information about this comes from the outside. In a simple case, this source is the config file. The program reads the port from it and starts the server exactly as it needs to do on a specific machine.

    In more complex scenarios, the file is not compiled by a person but a special program – a configuration manager. The manager stores information about network topology, machine addresses, and database access parameters. On request, it generate a config file for a specific machine or network segment.

    The process of passing parameters to an application and accepting them is called configuration. This step in software development deserves close attention. When it is done well, the project easily goes through all the stages of production.

    Read more →

  • Можно ударить по голове

    Недавно я употребил в блоге фразу: если не выстрелит, ей можно ударить по голове (речь о втором издании книги). Это отсылка к фильму Snatch, в русском переводе “Большой куш”. Вспомнил, как мы с приятелем будучи подростками смотрели гоблинский перевод и ржали над матами. А ещё вспомнил, что даже тогда заметил одну деталь, связанную с этой фразой.

    Напомню, её несколько раз произносит торговец оружием Борис. Он толкает покупателям откровенный хлам. Покупатель взвешивает оружие и замечает — что-то тяжеловато. На что Борис отвечает: тяжесть — это надёжность. Если не выстрелит, им можно ударить по голове.

    Фраза звучит несколько раз, и очевидно, в какой-то момент она должна сыграть. Поскольку мы в комедии, нелепый тезис должен сработать при нелепых обстоятельствах. Другими словами, повторяя некую фразу, режиссер подводит зрителя к ситуации. И тут нас ждёт разочарование — в случае “не выстрелит” режиссер не уделил шутке внимания.

    Томми, партнер главного героя, покупает нерабочий пистолет. Позже он испытывает его из окна машины, и оружие дает осечку. Но в момент, когда Турецкого готовы убить, Томми наставляет пистолет на бандитов и тем спасает Турецкого. Таким образом выполняется только первая часть шутки — не выстрелит.

    Ещё подростком я понял, что надо было обыграть фразу по-другому. Во-первых, когда Турецкий предлагает выстрелить из машины, Томми должен был отказаться. Якобы потому, что Борис — надёжный продавец как и его товар, поэтому сомневаться нет смысла. На самом деле Томми боится оружия, и это только бы усилило ожидание шутки.

    Когда на Турецкого нападают бандиты, один из них душит его. Томми пытается выстрелить, но пистолет не работает. В глазах Турецкого ужас — пропала последняя надежда, ведь на физические способности Томми рассчитывать не приходится. Томми мечется, его взгляд падает на нерабочий пистолет. Он вспоминает напутствие продавца, берет пистолет за ствол и бьет бандита по голове. Тот сползает с Турецкого. Оба героя переводят дух, молча смотрят на оружие и кивают. В их глазах проскальзывает “действительно, им можно ударить по голове”.

    Так сбывается нелепое пророчество. В этом варианте раскрыты обе части шутки, и согласитесь, это было бы смешнее (в рамках криминальной комедии). Конечно, на словах звучит слегка коряво, но режиссёр на то и нужен, чтобы всё это обыграть камерой, мимикой, диалогами.

    Морали нет, просто наблюдение. Уже давно замечаю за собой, что после фильма обдумываю отдельные сцены, чтобы найти более удачные повороты сюжета, диалоги или черты персонажей. Эта заметка — попытка зафиксировать одну из таких идей.

Страница 1 из 53