Forwarded from partially unsupervised
Почему в software engineering так сложно с оценками сроков? Потому что зачастую практически невозможно на глазок оценить глубины кроличьей норы, если речь идет о чем-то сложнее перекраски кнопки на лендинге.
Вот небольшой пример. Есть сервис на питоне, в котором некоторые запросы начали тормозить. Хочется найти эти запросы, для этого - добавить в логи какой-то
Но в мире асинхронного питона нельзя просто хранить какой-то id на уровне треде, т.к. тред может переключаться между запросами в процессе await, нужно использовать ContextVars. Чтобы прикрутить ContextVars, нужен Python 3.7+, нужно обновиться. В процессе обновления выясняется, что некоторая старая версия библиотеки официально не поддерживает новый питон, нужно собрать ее руками. Методом проб и ошибок находим коммит, с которого собиралась старая версия для старого питона, собираем для нового питона - результаты не сходятся, тесты падают!
Для начала нужно собрать минимальный воспроизводимый пример (в моем случае получился Dockerfile на 50 строк и примерно столько же Python-кода). Разбираем билд и видим, что библиотеке нужен с десяток shared зависимостей, для которых не всегда указаны версии. Можно найти какие-то древние логи на CI-сервере, который собирал библиотеку для старого питона, и из них достать какие-то куски информации. Их не хватает, и версии приходится перебирать бинарным поиском. Версии подобраны, они конфликтуют друг с другом, и склеить их вместе можно только странным перебором
На все эти развлечения ушло уже три дня, и я не могу сказать, что приблизился к заветным
Вот небольшой пример. Есть сервис на питоне, в котором некоторые запросы начали тормозить. Хочется найти эти запросы, для этого - добавить в логи какой-то
request_id
.Но в мире асинхронного питона нельзя просто хранить какой-то id на уровне треде, т.к. тред может переключаться между запросами в процессе await, нужно использовать ContextVars. Чтобы прикрутить ContextVars, нужен Python 3.7+, нужно обновиться. В процессе обновления выясняется, что некоторая старая версия библиотеки официально не поддерживает новый питон, нужно собрать ее руками. Методом проб и ошибок находим коммит, с которого собиралась старая версия для старого питона, собираем для нового питона - результаты не сходятся, тесты падают!
Для начала нужно собрать минимальный воспроизводимый пример (в моем случае получился Dockerfile на 50 строк и примерно столько же Python-кода). Разбираем билд и видим, что библиотеке нужен с десяток shared зависимостей, для которых не всегда указаны версии. Можно найти какие-то древние логи на CI-сервере, который собирал библиотеку для старого питона, и из них достать какие-то куски информации. Их не хватает, и версии приходится перебирать бинарным поиском. Версии подобраны, они конфликтуют друг с другом, и склеить их вместе можно только странным перебором
apt install ... && apt remove ... && apt install
. На все эти развлечения ушло уже три дня, и я не могу сказать, что приблизился к заветным
request_id
. А ведь сторонний наблюдатель с навыками эффективного менеджера вполне мог бы возмутиться: "че там делать вообще? завел переменную и клади в лог, делов-то".Forwarded from partially unsupervised
Иронично, что даже в этом примере кроличья нора в итоге оказалась ощутимо глубже, чем я думал.
Сервис, над которым я работаю, не просто асинхронный, но местами еще и многопоточный: тяжелые операции живут в отдельных тредах. Их как раз и хочется трейсить больше всего. Соответственно, вдобавок нужно прокидывать
Здесь могла быть классическая картинка про многопоточность.
Сервис, над которым я работаю, не просто асинхронный, но местами еще и многопоточный: тяжелые операции живут в отдельных тредах. Их как раз и хочется трейсить больше всего. Соответственно, вдобавок нужно прокидывать
request_id
внутрь этих тредов, обновлять там логгеры, и, конечно, нужно реализовать все это в общем виде (больше замыканий богу замыканий!). Здесь могла быть классическая картинка про многопоточность.
Блог*
#prog #rust #rustlib #serde #amazingopensource Хозяйке на заметку Подборка библиотек для работы с serde от замечательного Толяна dtolnay. erased-serde — трейты из serde со стёртыми типами. Позволяют сделать из (де)сериализаторов трейт-объекты. Обычно это…
#prog #rust #rustlib #serde
serde-diff
"A small helper that can
1. Serialize the fields that differ between two values of the same type
2. Apply previously serialized field differences to other values of the same type."
serde-diff
"A small helper that can
1. Serialize the fields that differ between two values of the same type
2. Apply previously serialized field differences to other values of the same type."
GitHub
GitHub - amethyst/serde-diff: Utility for comparing two structs and re-applying the differences to other structs
Utility for comparing two structs and re-applying the differences to other structs - GitHub - amethyst/serde-diff: Utility for comparing two structs and re-applying the differences to other structs
Хочешь зарабатывать много денег? Мечтаешь войти в высшую лигу разработки? Хочешь войти в IT, но не знаешь, как начать?
Сочувствую.
Сочувствую.
🔥1
Читаю тут, почему строки в Java и C# иммутабельные. Фактически, ответ — потому что языки г... Недостаточно мощные и не могут гарантировать ни thread safety, ни иммутабельный доступ к объектам. А вы говорите, что borrow checker не нужен.
👍1
Блог*
Читаю тут, почему строки в Java и C# иммутабельные. Фактически, ответ — потому что языки г... Недостаточно мощные и не могут гарантировать ни thread safety, ни иммутабельный доступ к объектам. А вы говорите, что borrow checker не нужен.
Кстати, в Java 7 поменяли семантику метода substring: раньше новая строка переиспользовала хранилище оригинальной строки, а после этой версии делает новую строку в хипе. Оба варианта так себе: первый использует слишком много памяти, если подстрока берётся от очень большой строки (старая-то никуда не девается, новая ссылка не даёт сборщику мусора собрать старую строку) — собственно, это и было причиной для внесения изменений, а новый вариант потребляет излишнюю память, если программа оперирует большим количеством подстрок одной и той же строки (скажем, в программе какой-то свой парсер).
Новый вариант, кстати, строго хуже: в старом варианте можно было форсировать выделение в куче при помощи костыля вида
Новый вариант, кстати, строго хуже: в старом варианте можно было форсировать выделение в куче при помощи костыля вида
string sub = original.substring(from, to) + "";
, а при помощи нового варианта получить поведение, как в старом варианте, нельзя.Programcreek
The substring() Method in JDK 6 and JDK 7
How substring(int beginIndex, int endIndex) method works in JDK 6 and JDK 7 are different. This article use a diagram to illustrate their difference. Knowing
Блог*
Читаю тут, почему строки в Java и C# иммутабельные. Фактически, ответ — потому что языки г... Недостаточно мощные и не могут гарантировать ни thread safety, ни иммутабельный доступ к объектам. А вы говорите, что borrow checker не нужен.
А вот ещё пример из Go. Мутабельных строк там нет (есть лишь string.Builder). Строка в рантайме — это структура с двумя полями: адрес и длина, а слайс — структура с тремя полями: адрес, длина и ёмкость. Технически ничто не мешает преобразовать слайс байт в строку, просто отбросив поле
Cap
(что, собственно говоря, и происходит в strings.Builder.String), но в общем случае это некорректная операция, потому что слайс мутабельный (всегда, иммутабельной версии слайса просто не существует), а строка — нет. Как результат, каст слайса байт в строку выделяет память в куче и копирует данные. Это лишняя работа, особенно если используемая строка почти сразу отбрасывается — например, если строка используется как ключ для map
. В какой-то момент в компилятор Go запилили peephole-оптимизацию, которая распознавала паттерн someMap[string(bytesSlice)]
и переписывала на реальный каст на фейковый, который просто копирует указатель и длину из слайса.pkg.go.dev
strings package - strings - Go Packages
Package strings implements simple functions to manipulate UTF-8 encoded strings.
🤣2
Forwarded from rusta::mann
У меня новый фаворит среди изменений, предложенных ревьювером.
Code Review might not make your code better, but it definitely will make it doper.
#codereview
Code Review might not make your code better, but it definitely will make it doper.
#codereview
👍1
#prog #rust #rustlib
Библиотека (и плагин для cargo), которая позволяет найти минимальную версию Rust, с которой проект собирается. Использует, увы, линейный поиск вместо бинарного.
https://github.com/foresterre/cargo-msrv
Библиотека (и плагин для cargo), которая позволяет найти минимальную версию Rust, с которой проект собирается. Использует, увы, линейный поиск вместо бинарного.
https://github.com/foresterre/cargo-msrv
GitHub
GitHub - foresterre/cargo-msrv: 🦀 Find the minimum supported Rust version (MSRV) for your project
🦀 Find the minimum supported Rust version (MSRV) for your project - foresterre/cargo-msrv
Forwarded from Zero Dereference
A simple and well-documented microkernel operating system released under public domain.
https://resea.org/
https://resea.org/
👍1
Блог*
#prog Переписал по работе одну утилиту для анализа логов. Раньше для разбора строк использовались регулярные выражения, а я заменил на наколенный лексер. В результате утилита, которая почти 23 гигабайта перемалывает за чуть больше, чем за 5 минут, стала на…
В утилите (после моих изменений) используется массив строковых значений, с которыми строчки логов должны обрабатываться отдельно. Для более быстрого поиска этот массив упорядочен, а значение ищется бинарным поиском. На код-ревью коллега мне совершенно справедливо указал, что отсортированность нужно как-то поддерживать. Не вопрос: пишем
К сожалению, сравнение строк в const fn пока использовать нельзя, так что константную функцию сравнения строк пришлось писать самому 😠
const fn is_sorted(strings: &[&str]) -> bool
— благо после релиза Rust 1.46.0, разрешившим циклы в const fn, это весьма легко — и пишем отдельно константу const _ASSERT_IMPORTANT_ARRAY_IS_SORTED: [(); 1] = [(); is_sorted(&IMPORTANT_ARRAY) as _];
— и теперь программа не собирается из-за несоответствия типов, если массив не отсортирован. Проблема решена.К сожалению, сравнение строк в const fn пока использовать нельзя, так что константную функцию сравнения строк пришлось писать самому 😠
Linker Unsafe
Мой новый рисунок компилятором по консоли
Впрочем, ничего нового. Типичный дизель.