LINUX.ORG.RU
ФорумTalks

Программистских баек тред

 ,


0

2

Давайте, что ли, откроем локальный филиал башорга и твиттера на тему разработки. Можно рассказывать занимательные и не очень истории из жизни, байки, мемы и просто «как я провел день».

Начну.

История первая.

У меня кусок админки управляет кучкой фоновых процессов. Не напрямую, а через прослойку-супервизора. Прослойку я написал на PHP, чтобы задействовать уже готовые функции админки. А чтобы управлять фоновыми процессами, потребовалось на php из подручных средств соорудить аналог pidfile_open (3). Вот такой:

function readPidfile($pidfile) {
    /* XXX: Race conditions are everywhere. But who cares? */

    if (!file_exists($pidfile)) {
        /* No such file - daemon not running */
        return false;
    }

    $f = fopen($pidfile, "r");
    if (!$f) {
        /* Failed to open file - daemon probably not running */
        return false;
    }

    if (flock($f, LOCK_EX | LOCK_NB)) {
        /* Able to acuire lock - daemon not running */
        fclose($f);
        return false;
    }

    /* Return PID */
    $pid = fgets($f);
    return $pid;
}

Вот смотрю и думаю: какое-то нецелевое использование «макропроцессора для HTML-страниц». Ну а почему бы и нет. Работает же.

История вторая.

Сегодня пришлось повоевать с кодировками в icecast. icecast к кодировкам оказался не очень приспособлен. Вот написал им, может замерджат мой патч: https://gitlab.xiph.org/xiph/icecast-server/-/issues/2423

Но что-то сомнительно. Ход очевидный, но почему-то сами они его не делали.

Ответ на: комментарий от vel

Выкини file_exists(). Оно тут нафиг не нужно.

Выкини file_exists(), отключи ворнинги. Неа.

Кроме того, оно еще кеширование использует.

Так правильно?

    clearstatcache(true, $pidfile);
    if (!file_exists($pidfile)) {
        /* No such file - daemon not running */
        return false;
    }
wandrien ★★
() автор топика
Ответ на: комментарий от fernandos

Переменная для переменной.

Именно. Мы же не в 84-м, чтобы экономить переменные.

$f contains PID

Вместо переменной с названием $pid теперь комментарий, в котором написано ровно то же самое, так еще и с форматированием на три строки.

К тому же комментарий ошибочный.

wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от fernandos

Не понял про is_readable(). Он использует тот же самый кэш.

Для того чтобы оно пыталось каждый раз очищать кеш? После file_exists вставьте.

А если какая-то другая функция скрипта вызовет stat() на этот же файл? П — предсказуемость.

Для того чтобы оно пыталось каждый раз очищать кеш?

Еще и Э — экономия.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Вместо переменной с названием $pid теперь комментарий, в котором написано ровно то же самое, так еще и с форматированием на три строки.

По-хорошему надо документировать параметр функции, но мы же не в 84, можем позволить себе переменные.

fernandos ★★★
()
Ответ на: комментарий от fernandos

return (int) fgets($f);

В одном языке без типов однажды пришлось делать что-то вроде return (1 * fgets($f)), чтобы точно отдавалось целое во внешнюю библиотечную функцию. Некоторое количество нервов оставил на этом месте.

Toxo2 ★★★
()
Ответ на: комментарий от fernandos

По-хорошему надо документировать параметр функции, но мы же не в 84, можем позволить себе переменные.

Параметр какой функции вы собрались документировать?

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Не понял про is_readable()

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

А если какая-то другая функция скрипта вызовет stat() на этот же файл?

Он разве не на процесс? Или у вас параллельный пхп?

А вам стат-кэш нужен? Где-то был ПР, отключающий его.

fernandos ★★★
()
Ответ на: комментарий от Toxo2

Однажды реализовывал библиотеку для работы с бинарным форматом. У формата было две версии, с первой было всё в порядке, описание было паршивое, порядок байт указан не был, но я предположил, что это big-endian, ибо извлечённые данные бились (сходились с ожидаемыми), реализовал, и всё нормально работало. Второй формат расширял первый, убирая часть полей и добавляя много новых, большинство из которых в обоих форматах либо short, либо строки. Но одно поле не билось. Одно единственное.

Почесал репу, поменял порядок байт на little-endian, поле стало биться. Хм. Подумав хорошенько, я понял, что с первым форматом мог вполне ошибиться, ведь, ни с short, ни со строками в однобайтовой кодировке из-за порядка байт никаких проблем быть не может. Ну, ОК. Доделал, начал тестить, первый формат таки сломался (часть кода была общая), нашлись интовые (int32) поля. Вернул в зад, поставил, выставил разный порядок для двух форматов. Протестировал второй, оказалось, что всё равно не бьются общие поля с первым форматом. В этот момент я уже не понимал, что происходит и вычитывал код, выискивая, где же я натупил. Целый день ломал над этим голову, проверяя самые бредовые предположения.

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

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 3)
Ответ на: комментарий от fernandos

Он разве не на процесс? Или у вас параллельный пхп?

У меня скрипт, который работает в режиме PHP_SAPI === ‘cli’.

Вопрос не так надо ставить. У вас в вашем варианте поведение функции начинает зависеть от поведения других частей кода. Без всякой на то необходимости и нужды вводите общий стейт.

Ну это же говнокод, извините.

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

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

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

Есть малая вероятность, что файл будет удалён между file_exists() и fopen(), и тогда я всё равно получу ворнинг. Но с такой мелочью я готов мириться. Главное, чтобы оно не сыпало мне этот ворнинг в логи постоянно.

А вот случай попытки читать из пид-файла, который мы не имеем права читать, как раз вполне тянет на разумный, полезный ворнинг:

php > $f =  fopen("/etc/shadow", "r");
PHP Warning:  fopen(/etc/shadow): failed to open stream: Permission denied in php shell code on line 1

И здесь нам поведение PHP полностью на руку. Так что глушить этот ворнинг проверкой на is_readable() нет никакого смысла. Пусть остаётся.

wandrien ★★
() автор топика
Ответ на: комментарий от WitcherGeralt

ведь, ни с short, ни со строками в однобайтовой кодировке из-за порядка байт никаких проблем быть не может

С short-то как раз может, разве нет?

wandrien ★★
() автор топика
Ответ на: комментарий от xmikex

Код должен читаться как хорошая проза.

wandrien ★★
() автор топика
Ответ на: комментарий от dimgel

А ты что ожидал?

Я еще и трезвый вечером субботы. :(

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

У меня скрипт, который работает в режиме PHP_SAPI === ‘cli’.

И что?

А вы знаете про кэш и предлагаете целенаправленно наговнокодить

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

А у другой функции, считывающий или изменяющий информацию о файле будет свой вызов clearstatcache. Таким образом кеша в системе попросту не будет, как и ненужных вызовов.

fernandos ★★★
()
Ответ на: комментарий от fernandos

А у другой функции, считывающий или изменяющий информацию о файле будет свой вызов clearstatcache. Таким образом кеша в системе попросту не будет, как и ненужных вызовов.

Понятно, говнокод.

К вопросу, почему не любят PHPшников.

как и ненужных вызовов.

Э - экономия.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

Понятно, говнокод.

Конечно, если вам плевать на производительность, дело ведь касается не UB, а одного предупреждения.

Э - экономия.

Экономия своего времени в ущерб производительности, да-да. И безопасности, вы ведь даже open_basedir не настроили.

fernandos ★★★
()

подсократил код ТС, подчеркнув самую мякотку:

function file_readable ($name) {
   $f=fopen($name,"r");
   if (!$f) return 0;
   flock($f, LOCK_EX | LOCK_NB);
   return 1;
}

MKuznetsov ★★★★★
()
Ответ на: комментарий от rupert

Интересное предложение, но кто бы тогда фиксил такие баги?

Они при многих даже довольно осторожных подходах к разработке на плюсах возникают достаточно часто. Этот я запомнил лучше всех потому что сам же и посадил (и он не проявлялся пока не были закончены работы по доведению новой платформы до пригодного к запусу тестов варианта).

GPFault ★★
()
Ответ на: комментарий от fernandos

Уже бегу оптимизировать функцию на пхп, которая срабатывает по таймеру раз в минуту. На пхп, Карл!

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

wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

Её не надо оптимизировать, её надо было сделать с начала правильно.

При чём я же не говорю писать маргинальщину типа isset($string[5]) вместо strlen($string) > 5.

fernandos ★★★
()
Ответ на: комментарий от Anoxemian

не пойдет?

пойдёт, так короче :-)

ps/ php неплохой язык, бяда с php-программистами..

MKuznetsov ★★★★★
()
Ответ на: комментарий от wandrien

Функция работает неоптимизирована, неправильно выразился, прошу прощения.

А неоптимизирована она потому, что вместо практически mutation-free получилась слепая функция, которая очищает кэш просто так. Хотя это немного нудная тупая придирчивость.

К слову, у меня не удалось заставить file_exists кэшировать результаты, размер файла кэшируется, его наличие — нет. Размер кеширует, а наличие нет.

А, и ваш код не сработает, если где-то выше вы заблокируете этот файл.

fernandos ★★★
()
Последнее исправление: fernandos (всего исправлений: 1)

readPidfile

Фу таким быть. Ладно ещё кемел кейс, на него я с зажатым носом готов смотреть. Но почему неконсистентный? Почему не readPIDFile или хотя бы readPidFile?

eternal_sorrow ★★★★★
()

Можно рассказывать занимательные и не очень истории из жизни

Нвидия г-но АМД г-но Гугл это вообще нечто

корпорациям нас-асть на пользователей и «кодописанием» всего занимаются непойми кто за 10к р в месяц

в 2021 году пишут копмиляторы которые не могут скомилировать код длиннее 10 строк

готовые к продакшену решения и просто софт который не падает и работает откатывается к технологиям древних, за последние 10 лет не произошло апгрейда технологий а только даунгрейд или костыли и подпорки под старым кодом и технологиями которым 20-30 лет

«гранды» за баги и «самер оф коде» получают дружественные к корпорации компании вместо бонусов ежегодных

svv20624
()
Ответ на: комментарий от GPFault

кто бы тогда фиксил такие баги?

Ты их в заложниках своими багами держишь? Маладца!

rupert ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.