Telegram Web Link
Мой первый чат с коллегами про Rust
😁29👍5💩1
Мой первый онлайн по CS:GO. Надо же, 11 лет не играл ни во что, а руки-то помнят. 10 лет в кланах по батле - не шутка. Старичок потряс порохом и пошел дальше пилять свои PLC.

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

Но выход есть - правильные настройки thinkfan (для ThinkPad'ов) и алюминиевая подставка. Кстати, почему их практически перестали делать качественно? Лет 15 назад я купил совершенно добротную подставку от Cooler Master, весом килограмма в 3 чистого алюминия за какие-то жалкие 15$
🔥7👍6😁1
Первое правило суппорта: все врут

- у нас система периодически виснет
- вы опять логи на nfs кидаете?
- нет, мамой клянусь!
- покажите конфиг логгера
- log: /mnt/remote/nfs/blabla
- а почему он так называется?
- не знаю. я уточню у админов...
😁19👍16🔥4
IBM планирует уволить 7800 человек и заменить их AI. В основном сокращения коснутся HR.

Поставить смазливое фото на авку в LinkedIn и генерить сообщения, на которые никто не отвечает, может и ChatGPT.
😁17🔥2
Поскольку GPIO через sysfs в Linux давно депрекейтнули, а универсального вменяемого пока не завезли, давно хотел заняться кишками OPC UA. И у меня наконец получилось понять его дзен.

Уже как-то писал об этом чуде. Спецификация протокола занимает 600 страниц (или 800?) и на данный момент на рынке нет ни одного решения, которое бы отвечало ей на 100%. Производители спецификацию поддерживают частично, или "принимают к сведению", впрочем ситуация с совместимостью куда лучше, чем в том же Ethernet/IP.

Архитектуру OPC UA ненавидят многие - нужно иметь определенный тип ума, чтобы этим заниматься. Архитектура страшная. В своё время к ней приложила свою руку Microsoft (еще та, старая, с COM/DCOM), со всеми вытекающими, а потом полировала OPC Foundation, где около 1000 мемберов и каждый хотел что-то свое.

Начнём с соединения. Совершенно адская система авторизации, которая за многие годы включила в себя сумасшедшее количество способов и вариантов: aes128, aes256, basic128, basic256, с подписью пакетов, с подписью и шифрованием, авторизация по паролю, по ключу... В общем обрадую что на практике, если OPC крутится на fieldbus, авторизации обычно нет вообще.

Все переменные на OPC-сервере имеют Node ID. Причем оно может быть u32, String, GUID или даже Vec<u8>. Как сервера разбираются в этом чуде внутри себя - отдельная адская боль. Опять обрадую, на практике обычно используют второй вариант, иногда первый.

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

Типизация переменных. Как обычно, в попытках впихнуть невпихуемое, появились такие прелести, как XmlElement, LocalizedText (папки и display имена переменных можно, но не нужно, переводить локалями прямо на сервере) и некоторые другие. Обрадываю: на практике имеем дело только с привычными примитивами и массивами из них.

Каждая переменная имеет историю, которую может вести сервер. Когда поставили, что поставили, server timestamp, source timestamp и т.д. - попытка дидов скрестить контекст с TSDB. По сути, то что пытаются делать в Eclipse Zenoh - там зумеры переизобретают OPC (и может слава богу). Обрадываю: на практике я не видел, чтобы кто-то эту историю использовал.

Еще на серверах есть views, discovery, поддержка мульти-узлов, репликации и прочее-прочеее. Но если очень утрировать, OPC - это такая себе key/value database, правда с сумасшедшим набором легасни и непонятными в наше время наворотами. Не зря же 600 страниц (или 800?). А API - ну очень похоже на Beckhoff ADS. ADS явно строили на базе OPC, выкинув всё ненужное.

Впрочем, для продукта из 90х это круто. А еще круче, что стандарт прожил 27 лет и явно переживёт эти ваши Redis'ы.
👍5😁3
Телефон пищит, я кручу железку, коллега:
- Там емейл пришел что кто-то в твой вконтакте зашел из Буэнос-Айрэса
- На какое имя? Александр? Юрий? Иван?
- Михаил пишут
- Михаила не помню. Пусть забирают нах
😁29💩1
Гугл:

- ИИ это очень опасно. Нужно подождать
- Чего подождать?
- Подождать, пока мы выкатим свой. Мы мля чето протормозили...
😁64💩1
.
😁25🔥8👍2
Понадобилось кое-что крупное запрограмить на PL/PGSQL и встал вопрос, что писать многостраничные процедуры и функции в CLI как-то не очень весело.

Внезапно, это конечно же можно делать прямо из (neo)vim. И даже удобно.

Плагин называется https://github.com/kristijanhusak/vim-dadbod-ui
🔥6👍2😁2
Считаю, что проц-макросы в Rust нужно запретить. Проц-макросы генерят очень эффективный код (даже лучше чем GPT3). Проц-макросы - это черный ящик, пока мы не запустим специально cargo expand, мы не узнаем, что они там наворотили (ИИ хотя бы свой код показывает).

Проц-макросы отбирают рабочие места и несут серьезную угрозу человечеству. Самое страшное - в отличие от ИИ, требующего некоторых вложений на обучение, проц-макрос может написать любой человек, не специалист (а вдруг со злым умыслом?)
😁28👍5🔥2
Часто спрашивают "что почитать для продвинутого уровня в Rust?". Рекомендую вот эту книгу. Пошел освежить по атомикам, в результате узнал ещё некоторые вещи о потоках, которые в жизни упустил.

Если нету или жалко 40$, автор любезно приглашает прочитать всю книгу бесплатно на своём сайте. https://marabos.nl/atomics/
👍20
.
😁28👍5🔥4
Выложил в паблик экспериментальную платформу PLC под Linux - rPLC. Пока без анонса, только тут. Потихоньку начнем анонсировать к концу месяца.

Проблема насущная - наша EVA ICS v3 была платформой, которая решала множество задач, в том числе автоматизации. v4 - это только SCADA с упором на IaC и репликацию узлов. В результате часть клиентов не могут слезть с v3, а платить деньги CODESYS за их простенький Linux-PLC не желают (я и сам не желаю). Попытки сделать что-то удобное и рабочее вел с 2020 года, но наконец паззл сложился.

Это одна из первый PLC-платформ, где Rust используется как основной (и пока единственный) язык программирования, при этом применяется классический PLC-подход: есть общий контекст переменных, программы исполняются в циклах, а I/O максимально изолировано от программиста (пока из коробки есть Modbus, OPC UA ну и полная интеграция с EVA ICS. но можно легко расширять под другое).

Код-генерация - совмещает проц-макросы для программ и codegen для I/O и контекста.

Какой jitter можно добиться на Linux? На практике, при условии что хост не имеет лишней нагрузки или использует isolcpus - в пределах 120-150us, что примерно соответствует уровню, который декларируют Beckhoff в своих IPC (причем это на Supermicro E100-9AP-IA, где стоит довольно слабый Atom E3940). Опять же на практике - у нас нет задач, где циклы бегают быстрее 10ms и нужен jitter < 1ms. Да их вообще мало у кого есть, это больше для пиара.

Какие сертификации на это можно получить? Вопрос сложный, потому что в первую очередь сертифицируется ящик. Будем пробивать бюрократию.

Планы на будущее: порт под FreeRTOS (там сейчас стало получше с Rust), плагин под VS Code, Pro-версия (менеджер isolcpus и процессов из гуя, статистика с графиками и т.д.), реалтайм-тюнинг сети. И главное - есть хорошая идея по репликации контекста между процессами. Хотя, прямо сегодня конечно можно реплицировать через OPC.

Даю линк сразу на quick start, чтобы было понятнее: https://info.bma.ai/en/actual/rplc/quickstart.html

А репа тут: https://github.com/eva-ics/rplc
👍16💩1
Потратил целый день на тюнинг библиотеки на 200 строчек, но не жалею, так как наконец еще глубже появился повод разобраться с фьючерами в Rust.

Библиотека собственно - https://github.com/alttch/simple-pool, написал ее хз когда давным-давно. Идея простая - пул любых ресурсов, или можно с Unit использовать для ограничения количества выполняемых тасков (как рантайм-агностик семафор). Реализация сложнее.

Future, для тех кто не в курсе - это функция (точнее - объект, в котором одна обязательная функция poll), которая возвращает либо std::task::Poll::Ready<T>, если она отработала или Poll::Pending, если возвращать нечего и это просьба рантайму включить ее в лист ожидания. Из доступных инструментов общения с внешним миром у вас по сути есть только std::task::Waker. Клон waker вы можете отдать в другой объект, который, если появились новые данные, или как в нашем примере, новый ресурс, этот waker дергает и "будит" вашу функцию. Но на самом деле не будит, а только сообщает рантайму, что ее можно разбудить. Так работает в Rust весь async.

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

Задача кажется простой - так давайте, когда ресурс пришел в пул, дергать один первый waker и делов. И действительно, оно отлично работает. Пока вам не хочется делать фьючерам abort.

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

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

Итог. Единственная возможность у фьючера узнать (точнее - предположить), что его абортировали - это impl Drop. В Drop мы можем сообщить пулу, что мы дальше работать не будем и вместе решать, что делать. Если мы стояли в очереди - выбросить из нее наш waker. Если же waker уже был дернут, но мы так и не успели обработать данные - пул должен разбудить следующий Future. А с нами попрощаться.
👍15
Особенности массивов в Rust.

Массив в Rust может быть объявлен, как
let a = [0u8; 32];

либо
let a: [u8; 32] = <_>::default();

либо
let a: [u8; 33] = <_>::default();

? А вот и нет. Последний вариант работать не будет. Трейт Default для массивов в Rust имплементирован только до 32. Причем каждый от 1 до 32 с любью сгенерен вручную, и по факту представляет собой

let a: [T; 32] = [T, T, T, T, T....];

- Позвольте, - скажете вы, - но мы же можем объявить массив любого размера! Например let a = [0u32; 1024]

Правильно, можете. Потому что такой массив будет построен копированием, а u32 impl Copy trait. В случае же, если у вас будет

#[derive(Default)]
struct A {}

let a: [A; 33] = [<_>::default(); 33]; // или даже
let a: [A; 33] = [A{}; 33];

компилятор пошлет вас, потому что A не имплементирует Copy. При этом для массива до 32 элементов, вы можете продолжать использовать Default::default, потому что см. выше.

Так как же объявить массив на 33 элемента, используя Default::default? А вот так и объявляете - 33 раза по default. Инструменты вам дали, генерите как хотите. Если не умеете - можете копи-пастой.
👍6💩4🔥2😁2
clippy спасает вас не только от некрасивого кода, но и от потенциальных проблем
👍16🔥7😁5
отрицание: ну ведь не все дистры еще перешли...
гнев: оно же кривое и страшное!
торг: google, how to enable /etc/rc.local
депрессия: как же хорошо было с SysV init в лихие 90е
принятие: пишем сервисы для systemd
😁24🔥4💩2
Сегодня довелось покодить на JavaScript. Сую локальную переменную в Promise. Мысли в голове:

- проверь, что она Send
- посмотри под блоком, что она точно мувнулась
😁20👍15
А что я собственно кодил на JavaScript - я апдейтил JS-фреймворк нашей платформы автоматизации для написания сценариев этой самой автоматизации.

Основная автоматизация промышленных процессов происходит в fieldbus, где стоят контроллеры (для очень mission-critical, например при пожаре включить огнетушитель и сирену - эти вообще бывают механическими, без электроники, простой пример - пакетник у вас в щитке) и PLC (обычно для менее critical, например при пожаре включить аварийное освещение) задач.

Но fieldbus сложно и страшно апдейтить, поэтому любая SCADA тоже имеет некую систему автоматизации, которая в основном автоматизирует действия оператора (при пожаре отправить емейл шефу и включить в дополнении к сирене, голосовое сообщение в матюгальник), а оператор за этим наблюдает. В случае, если SCADA имеет веб-морду, а не является "толстым" клиентом с пультом и 12 мониторами, настолятельно рекомендуется все сценарии автоматизации крутить на backend, потому что браузер может банально отвалиться и сценарий не закончится.

Но на backend тоже надо получить доступ, а еще там надо как-то это все конфигурить, а еще там обычно нет JavaScript, а сценарий нужен срочно. Поэтому веб-девелопер берет функции, которые он вешает на кнопки гуя и с горем пополам пишет client-side сценарий.

Раньше я бы за такое бил по рукам. Но теперь я стал мудрее и решил это возглавить. Если разработчики хотят писать клиентские сценарии, не смотря на отсутствие вменяемого функционала - им нужно дать его наличие. А мудрее меня сделал Rust. Принты для дебага тоже всегда и везде использовать запрещали десятилетиями. Но потом сдались и влепили std::dbg!.
👍11💩1
А на андроиде сейчас никак нельзя уведомления вырубить? Чтобы не совсем, а висел где-то в трее счётчик и иконки, как на десктопе.

Помнится раньше так было. Потом придумали ебучие тосты, которые лезут прямо на экран, когда занят. Потом ещё более ебучие bubbles, ну эти хоть выключаются.

Как будто бы телефон создан, чтобы по нему звонили и писали.
😁22👍6
2025/09/17 06:10:05
Back to Top
HTML Embed Code: