Telegram Web Link
За три месяца работы с ELBUS, который мы делали можно сказать лично под свои хотелки, у меня наконец сформировался список требований к идеальному брокеру сообщений, не важно IPC это или публичная сеть.

- Pub/Sub - понятно. Паттерн отлажен и более-менее хорошо работает у всех

- Но кроме Pub/Sub обязательно нужно P2P. Нет, можно конечно поставить отдельный сервер для P2P, а отдельный для Pub/Sub, но зачем два, если можно один

- Для P2P клиент должен обязательно иметь возможность идентифицировать себя уникальным ID. Которое может совпадать с логином/аккаунтом, или клиенту может даваться возможность выбрать из списка допустимых для него.

- P2P в 1% случаев нужен для доставки сообщений, в остальных 99% на него сразу же вешают RPC. На практике, P2P-сообщения ни для чего кроме RPC не нужны в принципе

- Pub/Sub тоже позволяет устроить P2P, но клиентам приходится либо шифровать коммуникации, чтобы их не слушали остальные, либо сервер приходится настраивать таким образом, чтобы клиент имел доступ для чтения-записи в определенные топики, причем это нужно делать под _каждую_ P2P-пару

- Атомарность операций подписки/отписки и публикаций. В MQTT сервер отдает токен, по которому можно проверить, что операция прошла успешно, в нашем PSRT такие операции атомарны из коробки. Сколько было срачей по этому поводу, и тут ВНЕЗАПНО Eclipse наконец выкатывают асинхронный paho_mqtt под Rust, в котором токены - фьючеры, на которые можно сразу ставить await. Если протокол не позволяет атомарные операции, юзеры потребуют их на стороне клиента

Следующая цель - полноценный брокер по RS485
👍5🔥5
Похоже понимаю, почему меня так затянуло в эти все промышленные протоколы и уже лет 10 не отпускает - в детстве у меня был компьютер, на котором были всего две игрушки: debug.exe и norton disk editor. Эти ваши вебы и кубернетисы - хорошо, но душа не лежит.

Занятно погружаться в технологии, где в пейлоадах исчезают буквы. Но еще интереснее, когда в них исчезают и цифры (это я на слайде смотрю в осциль на RS485, который передает битые данные).
👍27😁1
- У нас бага на одном из серверов в облаке - данные периодически приходят с 2-сек задержкой
- Остальные сервера в порядке?
- Да
- Сожгите этот сервер
- Простите, вы точно техподдержка?
- Сожгите. Возможно внутри ведьма
🔥14👍7
После пары лет серьезного кодинга на Rust

- у тебя есть свой struct Error. Это крутой и любимый Error. Он умеет конвертировать себя из сотни других Error'ов, а потом себя в 20 разных типов сериализации и протоколов. Ты любишь свой struct Error, впрочем, тайно мечтаешь заменить его на trait

- у тебя есть свой собственный Value для Serde. Ты обожаешь свой Value, хотя давно подозреваешь, что 90% функций его имплементации применял один-два раза

- у тебя есть целая коллекция своих proc-макросов. Половина конечно ты уже не помнишь что делают, но пусть будут. В том числе, обязательно свой собственный derive на FromStr и Display для enum

- тебя пугает, когда не обойтись без mut self

- ты давно дружишь с коровой. Да что дружишь - у тебя стадо своих коров

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

- найдя нужную функцию на docs.rs, ты сразу жмешь "source"

- ты начал заменять shell-скрипты Rust'ом

- ты и borrow-checker уже имеете ментальную связь. И вы оба рыдаете, когда логика не позволяет сделать без Clone

- ты больше не проверяешь код clippy::pedantic. Ты коммитишь в clippy::pedantic
👍23👎3🔥2
Столкнулся тут с таким критерием выбора ентерпрайз-софта менеджерами - чем больше весит, тем лучше. Тяжесть - это надежно (ц)

Это к вопросу оптимизации размера бинарников на Rust. Иногда оно вредно.
👍7😁3
Еще из опыта - как определить что человек хорошо програмит на языках низкого уровня?

Мидл может без гугла и автокомплита правильно написать SeqCst (seq_cst)

А синьер может без гугла даже сказать, как оно расшифровывается
👍6🔥1
Скажите, коллеги, а для хорошего кодинга на Расте действительно полезно аниме смотреть?

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

https://github.com/divi255/ttycarousel

Предлагаю кому тоже нехер делать - можно поучаствовать, пооптимизировать. Думал может карусель бесконечным итератором сделать - но это уже, пожалуй, перебор.

Может еще каких анимаций добавить?
👍4
Я всегда срал в гит, и это моя слабость. Меня ругали за это коллеги, знакомые и просто прохожие люди. Но у меня два ноутбука и десктоп, и я привык синхронизировать код через гит. Поэтому 99% моих коммитов выглядят как "fix", "wip" и прочее подобное.

Наконец мне это надоело самому и я купил умную книжку аж за 50$. А там написано "срите дальше, но в свои ветки. а потом у вас есть git rebase и git reset - - soft".

Хороший совет дорого стоит. Теперь я и дальше сру в гит, но уже по науке.
👍29😁12💩3🔥1
(в чатике уже обсудили)

Допустим, вы запускаете в Linux процесс под рутом, которому нужно что-то прочитать или подключиться/забиндиться на сокет, а потом дропнуть привилегии до условного <nobody>/<nogroup>.

Почему-то интернет забит абсолютно неправильными примерами, как это делать. А потом опять "хакеры слили базы" и "виноваты рукожопые админы".

Итак, для смены пользователя текущего процесса мы вызываем libc::setuid(%uid_nobody%) (os.setuid в этом вашем питоне, nix::unistd::setuid в этом вашем расте и т.д.). Вызываем, понятно после смены группы, потому что если мы станем не рутом, то уже группу себе не сменим.

Так что сначала мы меняем группу. Как? Ну очевидно же что libc::setgid, как в миллионе каких-то примеров из гугла.

А вот и нихера.

libc::setgid не устанавливает процессу единую группу, а переключает её. В случае работы под рутом, вы можете выбрать любую группу, и она будет _добавлена_ в список групп процесса и выставлена по-умолчанию. Тоесть, если процесс был запущен как root:root, а вы вызвали libc::setgid(%gid_nogroup%), то процесс будет иметь обе группы - и nogroup (по-умолчанию) и root, а значит иметь право читать/писать всё в системе, куда имеет доступ группа root.

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

Перед libc::setgid нужно обязательно вызвать libc::setgroups([%gid_nobody%]). Этот вызов выбрасывает у процесса все группы, кроме %gid_nobody% (добавляет её, если нет), но при этом процесс всё еще работает с gid=root(0). Далее, делаем libc::setgid. Потом libc::setuid. И всё работает как надо.

Тест для примера (пускать под рутом)

так права на группу остаются
echo "hello" > test.txt;chmod 640 test.txt
echo "import os; os.setgid(65534); os.setuid(65534);print(open('test.txt').read())"|python3

а так всё в порядке, доступа нет
echo "hello" > test.txt;chmod 640 test.txt
echo "import os;os.setgroups([65534]);os.setgid(65534);os.setuid(65534);print(open('test.txt').read())"|python3
PermissionError: [Errno 13]
👍20🔥10
Одна из основных проблем любой pub/sub модели - медленный клиент в подписках на события. Какую бы вы ни ставили задачу, брокер/сервер всегда должен иметь защиту "от дурака", иначе на проде дурак обязательно вылезет.

Как реализовывается типичная pub/sub модель: брокер регистрирует каждому клиенту некий канал и при возникновении события (сообщения в топик, директа или бродкаста) - собирает подписчиков и плюет копию события в их каналы. Если же в цепочку стройных и быстрых клиентов затесался тормоз, ситуация может развиваться в следующих вариантах:

1) Очередь у медленного клиента вырастает до необъятного размера и брокер умирает от недостатка памяти (привет любителям unbounded channels)

2) Постепенно все обработчики событий останавливаются, ожидая когда же тормоз разрулит свою очередь, что как правило заканчивается не так печально как в предыдущем варианте - все клиенты брокера, включая тормоза, отваливаются по таймауту и переподключаются обратно (если умеют)

3) Правильный вариант - перед отправкой события в очередь, проверяем или она не заполнена полностью. И если да - моментально и безжалостно убиваем все соединения клиента, с желательным сообщением админам. Ибо работоспособность стройного коллектива - важнее, чем работоспособность отдельного тормоза. Исключение - если клиент "внутренний", т.е. работает в том же процессе что и брокер, тут вешаем всё и ждём. Но админам всё равно жалуемся.

Еще есть вариант чтобы брокер просто игнорировал отправку новых сообщений тормозу, пока тот не разберется с очередью. Но так делать - нехорошо и западло.
👍16👎1🔥1
Дошли мои шаловливые ручки обновить rmodbus - наш in-house Modbus stack. Во-первых нашлись пара багов, во-вторых в наше время все внезапные numeric overflows принято проверять, а не оставлять проблему на юзера, в третьих, это проект от 2019 года и 150 предупреждений от clippy мне не очень нравились.

Так что заливаю обнову. rmodbus - это не клиент и не сервер, а std/nostd кодек для модбаса + контекст-менеджер для слейвовых embedded-устройств.

https://crates.io/crates/rmodbus
👍6
В Rust у примитивных типов нет методов взять-поменять бит, потому что считается что каждый програмер умеет это делать сам. Но на практике пограмеры делятся на а) ленивых и б) глупых, в связи с чем crates.io забит тонной всяких всячин для реализации манипуляций с битами, основная функция которых опять же сводится к взять-поменять.

У меня конечно есть для этого свой, но не крейт - такую мелочь публиковать в крейт рука не позволяет. Но я вот задумался - а можно ли еще больше уменьшить код? По-моему вариантов уже нет. А у вас?

pub trait BitMan {
fn get_bit(self, bit: u32) -> bool;
fn with_bit(self, bit: u32, value: bool) -> Self;
}
macro_rules! impl_bitman {
(for $($tp:ident),+) => {
$(impl BitMan for $tp {
fn get_bit(self, bit: u32) -> bool {
if bit >= $tp::BITS { false } else { self >> bit & 1 != 0 }
}
fn with_bit(self, bit: u32, value: bool) -> Self {
if bit < $tp::BITS {
if value { self | 1 << bit } else { self & !(1 << bit) }
} else { self }
}
})*
};
}
impl_bitman!(for u8, u16, u32, u64, u128);
👍3💩2
А вот такие вещи в BIOS стали радовать. Дожили
👍10🔥5
Thinkpad T/P Gen2 традиционно поражают наличием опций и инструкций под Linux прямо от производителя. В целом счастье уже есть.

В BIOS выпилили переключение между дискретной и гибридной графикой. Оно больше не нужно - Optimus теперь работает прямо из коробки.

Себе взял T15P а не P15 (хотя в целом T15P это P15V, только GTX вместо Quadro), по причине непонятного отсутствия в магазинах экранов с UHD у последнего. Экран весьма радует. Правда к традиционной ебле с линуксом на десктопе добавляется ебля с DPI в половине софта.

С i7 11800H конечно весьма греется и надо колдовать с ACPI (советую сразу менять фирмварьное на thinkfan). Но Rust очень и очень рад 16 виртуальным ядрам.
👍9
Мощный ноут и моя тяга к перфекционизму.

У меня и раньше были мощные для своего времени ноуты, но при примерных размерах в 18" и толщине в 4 сантиметра, термал-менеджментом можно было пренебрегать, полагаясь на штатный из BIOS/фирмварь. Штатный тупил, гудел, подлил, но в целом как-то справлялся. Но 15", в которых 8 ядер по 2 потока (i7-11800H) и толщиной в 22 миллиметра - это уже не тягач и не феррари, а примерно болид из Формулы-1, и к нему нужен такой же ручной подход. Тем более такой ноут вы постоянно берете с собой, на колени и иногда даже в постель.

Стандартная фирмварь от Lenovo меня не порадовала. Вплоть до того, что в версии 1.11 для T15P/P15 они просто залочили кулер минимально на 2к оборотах и пользуйтесь как есть. Масла в огонь подливало, что на этих оборотах у кулера самый противный звук, так что пришлось разбираться.

В целом всё это разбирательство всегда и везде балансирует на треугольнике "шумно-горяче-медленно" и ничего нового в системах, которым нельзя увеличить физический размер, еще не придумали. Для начала, разберемся с "шумно-горяче".

Lenovo Thinkpad до сих пор сидят на старой доброй шине IBM, которую к счастью менять не собираются и которая за десятилетия была расхакана чуть менее, чем полностью. Поэтому ставим "options thinkpad_acpi fan_control=1" в modprobe и дальше имеем две опции - либо пишем свою логику для /proc/acpi/ibm/fan, либо ставим упомянутый thinkfan (есть во всех популярных линуксах), который со своей работой - балансировать между шумно и горяче вполне справляется.

Разберемся с "горяче-медленно". В целом, маневра нам тут не дадут - процы своими частотами управляют сами, мы можем переключать ядра только между "perfomance" и "powersave" на ходу (то что в BIOS обзывают "Max Perfomance" и "Balanced". Ставим cpupower (в Debian/Ubuntu он в linux-tools-common) и переключаем cpu governor в зависимости от задач. В powersave ядра могут скидывать частоты, вплоть до 800 мгц, в perfomance - держат запас, в данном случае около 2.3 ггц и при необходимости быстро разгоняются до 4х. Тоесть в принципе мы живём всё время в powersave, но если нужно сделать большую локальную компиляцию того же Rust - переключаем ядра одной командой в perfomance и наслаждаемся.

Тут есть нюанс по мониторингу - это ваше /proc/cpuinfo и оно же lscpu, давно нормально не работает. Настоящие частоты ядер нужно брать ручками, из /sys/bus/cpu/devices/*/cpufreq/scaling_cur_freq. Все ядра могут работать на разной частоте, поэтому то что выводят стандартные "виджеты для мониторинга" (тем более 99% из них лазит в /proc/cpuinfo) можно в принципе игнорировать.

Таким нехитрым образом, 99% вопросов из интернетов "я купил мощный ноут ХХХХХХ, а он медленный/горячий/шумный", в целом решаются. Если, конечно, шина позволяет тонкий подход.
👍18🔥5
Да, вдогонку к предыдущему. Intel Turbo Boost (старая добрая кнопка turbo), который собственно позволяет ядрам набирать частоты выше базового топа, переехал в /sys/devices/system/cpu/intel_pstate/no_turbo (включен по дефолту, можно выключать)

С отключенным turbo boost кулер в принципе не нужен никогда. Ну а на rustc включаем турбу и наслаждаемся 4-4.5ггц
👍5
Собственно покопавшись в фирмварях Lenovo нашел непонимание классической задачи автоматизации со стороны их дрим-тима:

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

- мы включаем кулер на режим 1, когда температура достигает 55 градусов
- но мы выключаем кулер (режим 0), только когда температура падает до 50

Иначе, поставив оба значения на 55, мы заебем мотор постоянными включениями-выключениями, как только температура начнет плавать вокруг 55 +/- (а она обязательно начнет, если не будет внешнего фактора). В случае лампочки - заебем реле, которое тоже механика. И т.п.

Тоже самое касается и дальнейших правил переключения режимов работы, но у электромоторов нет передач и там всё проще, у них два основных режима - стоит и едет.

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

Не делайте так никогда. И не пускайте таких людей к большим турбинам.
👍19
Тут мне напоминает в комментах коллега, что такой гэп называетя по науке гистерезис, а я вспомнил другую историю про термины.

Прораб: мне нужно чтобы в скаду всегда снимало первое значение, а потом применяло deadband

Мы: Уточни пожалуйста, deadband - это зона значений датчика, в которой показатели не выводятся, а ставится значение нижней границы..

Прораб: no way, это когда второе значение берется только если оно отлично от первого на указанное мной число!

Мы: то что ты говоришь - это delta, или step, но никак не deadband (ссылка на вики что такое deadband).

Прораб: меня не ебет их deadband, просто сделайте мне deadband, в том смысле в котором я знаю что такое deadband! У меня сроки горят! (понабирали тут яйцеголовых)

p.s. в таком случае считается в целом не дельта, а просто все значения округляются до некоего знаменателя до/после запятой и всё работает как надо, шаг получается автоматически. но мы уже не стали спорить и таки сделали deadband
👍8
Регистрация торговой марки в Британии.

В целом это просто, относительно дешево и быстро. Регистрируете, естественно, прямо на gov.uk, нахрен посредников. Вам необходим будет представитель в стране, это может быть юрлицо, так что если владеете компанией - можете поставить её как представителя, а себя - как владельца, например. С компании-представителя ничего не требуют - джентльмены верят друг другу.

С вас же попросят 170 фунтов с карты, или 100+100=200 за Right Start. Не берите Right Start - это наебалово. Вся помощь при регистрации заключается в том, что за +30 фунтов вам пришлют автоматически сгенеренный, но красивый PDF с похожими торговыми марками и переспросят: "а точно вы хотите продолжать"?

Если не будет возражений от конкурентов, процесс занимает примерно три месяца. Жулики и спамеры, в отличие от EUIPO, при этом пишут очень редко. Потом вы получаете сертификат в PDF на e-mail и вашу марку пропечатывают в журнале как registered.

10 лет, как везде, можете пользоваться.
👍13
2025/10/01 16:10:11
Back to Top
HTML Embed Code: