Если я правильно понимаю, то датчики, так и остаются датчиками, а все AI происходит на базовой станции(gateway), или через неё в облаке. Если на gateway ещё можно какие то нейронки засунуть(NVidia Jatson для примера) и с него управлять, то уж термостат, как был, так и останется.
И появлением JNA, и аннотаций в graalvm для прямого доступа к функциям нативных библиотек (и даже регистрам) а теперь и Panama, ну вас в гугле и на хабре забанили, читайте?
А кофейные результаты и страшные структуры оставьте хреновым проектировщикам.
Без упреков, но странно видеть JNI из 1997 года. Казалось бы после выхода Project Panama вся мобильная разработка должна была туда ломануться, вместо устаревшей технологии.
Туда ломанулись, но не дошли до чего то готового к "боевому использованию" или мобильный мир еще просто не готов?
Бегло глянул на изменения памятуя первый выпуск версии 0.5. Прогресс идет как в библиотеках, динамической линковке так и примерах. Рад, что проект развивается, не смотря на скептиков.
Обратную совместимость с ioctl в линукс так и не прикрутили смотрю, все же решили в свой HAL двигаться для SPI/I2C/GPIO and etc? Фактически же 99% констант уже перенесли, осталось сделать всякое константное, например вместо SPI_IOC_RD_MODE - KOS_SPI_IOC_RD_MODE и вперед
BTW: В linux 4.6 появилась работа с GPIO как с массивами, а не просто с одним пином.
Посмотрите в сторону gpiochip_info/gpioline_info/gpiohandle_request/gpiohandle_data
Простите, но данная статья вводит смуту и страшилки, но никак не говорит про ThreadLocal и все что якобы ниже написано.
Первый вопрос, который надо озвучить - а зачем его вообще использовать?
Самый "классический" пример - это держать там new SimpleDateFormat, который не thread-safe и имеет гигантские расходы на создание.
Второй "классический пример" - хранить там значение, нужное внутри всего потока.
Теперь пройдемся по примерам из статьи:
Утечки памяти из-за неправильного использования ThreadLocal
Да, мы получили 14 байтов + указатель, который добавился в поток. С учетом всего, что живет и собирается GC каждую секунду - ничего. Мы их не храним. Или как в примере с Tomat, у нас есть пул в 200 (по умолчанию, на сколько я помню) потоков, в которых мы храним эти цифры
Проблемы с пулами потоков
Вот тут как раз и нужно их не чистить (вспоминаем SimpleDateFormat). Вспоминаем Tomcat, у нас появляется thread-safe объект, который мы можем использовать без всяких проблем.
Или нам надо передать через поток Request-ID (для примера), чтобы вытащить в логи.
Неправильная инициализация и ошибки с null
Это не про ThreadLocal, а про инициализацию static в целом
Проблемы с производительностью
Когда у вас много потоков, каждый из которых создаёт собственную копию данных в ThreadLocal, это может привести к доп. накладным расходам на память.
Опять же, не проблема потоков, а проблема архитектуры-данных-ядер.
Память - это не производительность - это ресурсы.
Пройдемся по альтернативам.
Передача данных через параметры методов Вместо использования ThreadLocal, просто передавайте необходимые данные явно через параметры методов. Так код будет более предсказуемым и прозрачным.
Думайте для чего вы используете ThreadLocal, там должен быть не tread safe тяжелый объект. Который не надо создавать для каждого запроса.
Потокобезопасные коллекции Используйте классы ConcurrentHashMap или BlockingQueue, для безопасного доступа к данным между потоками.
ThreadLocal не предназначен для передачи данных между потоками, он нужен внутри потока.
Dependency Injection В DI-фреймворках (например, Spring) потоки управляются автоматически. Контексты изолированы без явного использования ThreadLocal
В CDI есть понятие application scoped и request scoped. Не дай бог вам создать тот же SimpleDateFormat в обоих контекстах.
Reactor и Vert.x Context В реактивных приложениях используйте контексты для асинхронного управления данными, минимизируя зависимость от потоков.
Context (по крайней мере в Vert.x) является аналогом @RequestScoped , не создавайте в нем тяжелые объекты. Они будут создаваться на каждый запрос.
С Loom, пока не работал ничего не скажу.
Личное мнение - не используйте советы из данной статьи. На вопросы - готов ответить
Привет, предложение для следующей статьи - Всё то же самое можно сделать через hibernate search, без logstash и вендорлока на elastic/lucene/open search. При чем можно индексировать только нужные поля.
Наблюдал совершенно обратную ситуацию с RPS. Только не на синтетическом кейсе, а готовом приложении. Натив это не только старт, но и меньше cpu/mem. Точных цифр не помню, но условно 15-30% там было. Вместо micronaut был quarkus
Вы правда не читали то на что это написали? Попробуйте ещё раз.
Но мысль понятна, если мы пишем фреймворк, для работы с железом, куда прикрутится сторонними разработчиками любое железо, то надо тестировать его на реальном железе(а нам как бы интерфейсы Линукс тестировать) и виртуализировать железо.
Как бы тут сказать. Все веб программирование научилось виртуализироваться, разработчики чипов - эмулирует работу на fpga. И только в эмбеддед - будь добр припаять провода. Только хардкор.
А давайте я вам еще усложню задачу... В этом фрэймворке есть эдак 600 интегрированных модулей которые тестируются параллельно.
Ну например интеграция с Oracle, DB2, MySql, Postgrees, Keycloak, AWS, K8S, Camel и еще очень длинный список.... Ну все вместе потащим куда то на железо? Только виртуализация, образы, контейнеры и где приходит embedded - наступает боль...
Проблема в том, что мне надо гонять фреймворк, драйвера к устройствам по CI в облаке. Т.е там может быть даже не ARM. Надо виртуально создать те же SPI/Serial интерфейсы и виртуальные устройства к ним. И как то оттестировать все.
Так что регистры сразу мимо. Виртуализация шин и устройств на Линукс нужна.
Ну то есть код лежит а github и тестируется job-ами на gitthub, где не ARM не подключенных устройств нету.
Сколько не думал, так и не смог решить задачу - допустим у нас есть embedded linux. Под капотом есть arm и какая то обвязка. А как собственно оттестировать работу с этой обвязкой? Эмулировать i2c, spi, serial, а поверх прикрутить виртуальные устройства вместо реальных датчиков и устройств.
Примерно как mook server для http.
Все, что выше тестируется легко. А вот уровень железных интерфейсов - боль. Не поделитесь?
А излучать простите куда, в вакуум? Там нет молекул как в атмосфере Земли, которым можно сбросить тепло
Даже сейчас у МКС были проблемы, как помните, с нагревом модуля до 55 градусов (если не путаю)
А тепло отводить как будут? :)
PgBouncer на своей стороне умеет PS кэшировать, вместо того же hikari. Но в целом спора нет, думать про архитектуру надо смолоду
В мире микросервисов пришли новые грабли - а именно когда то было 5 pod- ов а теперь 100 pod- ов. И у каждого на базу по 20 соединений.
Да, есть PgBouncer, но начинается беда с PS.
Если я правильно понимаю, то датчики, так и остаются датчиками, а все AI происходит на базовой станции(gateway), или через неё в облаке. Если на gateway ещё можно какие то нейронки засунуть(NVidia Jatson для примера) и с него управлять, то уж термостат, как был, так и останется.
Улучшить можно все.
И появлением JNA, и аннотаций в graalvm для прямого доступа к функциям нативных библиотек (и даже регистрам) а теперь и Panama, ну вас в гугле и на хабре забанили, читайте?
А кофейные результаты и страшные структуры оставьте хреновым проектировщикам.
Без упреков, но странно видеть JNI из 1997 года. Казалось бы после выхода Project Panama вся мобильная разработка должна была туда ломануться, вместо устаревшей технологии.
Туда ломанулись, но не дошли до чего то готового к "боевому использованию" или мобильный мир еще просто не готов?
Бегло глянул на изменения памятуя первый выпуск версии 0.5. Прогресс идет как в библиотеках, динамической линковке так и примерах. Рад, что проект развивается, не смотря на скептиков.
Обратную совместимость с ioctl в линукс так и не прикрутили смотрю, все же решили в свой HAL двигаться для SPI/I2C/GPIO and etc? Фактически же 99% констант уже перенесли, осталось сделать всякое константное, например вместо SPI_IOC_RD_MODE - KOS_SPI_IOC_RD_MODE и вперед
BTW: В linux 4.6 появилась работа с GPIO как с массивами, а не просто с одним пином.
Посмотрите в сторону gpiochip_info/gpioline_info/gpiohandle_request/gpiohandle_data
Простите, но данная статья вводит смуту и страшилки, но никак не говорит про ThreadLocal и все что якобы ниже написано.
Первый вопрос, который надо озвучить - а зачем его вообще использовать?
Самый "классический" пример - это держать там new SimpleDateFormat, который не thread-safe и имеет гигантские расходы на создание.
Второй "классический пример" - хранить там значение, нужное внутри всего потока.
Теперь пройдемся по примерам из статьи:
Да, мы получили 14 байтов + указатель, который добавился в поток. С учетом всего, что живет и собирается GC каждую секунду - ничего. Мы их не храним. Или как в примере с Tomat, у нас есть пул в 200 (по умолчанию, на сколько я помню) потоков, в которых мы храним эти цифры
Вот тут как раз и нужно их не чистить (вспоминаем SimpleDateFormat). Вспоминаем Tomcat, у нас появляется thread-safe объект, который мы можем использовать без всяких проблем.
Или нам надо передать через поток Request-ID (для примера), чтобы вытащить в логи.
Это не про ThreadLocal, а про инициализацию static в целом
Опять же, не проблема потоков, а проблема архитектуры-данных-ядер.
Память - это не производительность - это ресурсы.
Пройдемся по альтернативам.
Думайте для чего вы используете ThreadLocal, там должен быть не tread safe тяжелый объект. Который не надо создавать для каждого запроса.
ThreadLocal не предназначен для передачи данных между потоками, он нужен внутри потока.
В CDI есть понятие application scoped и request scoped. Не дай бог вам создать тот же SimpleDateFormat в обоих контекстах.
Context (по крайней мере в Vert.x) является аналогом @RequestScoped , не создавайте в нем тяжелые объекты. Они будут создаваться на каждый запрос.
С Loom, пока не работал ничего не скажу.
Личное мнение - не используйте советы из данной статьи. На вопросы - готов ответить
Чем то напомнило реактивные пулы на vert.x + mutiny - https://quarkus.io/guides/reactive-sql-clients#using
или hibernate reactive на том же mutiny
Ура, панама таки случится....
Пока начинать с JNA уходить для jvm mode.
Жаль только они так и не скрестили native API для Graal с Панамой и дупликация кода для jvm/native пока останется
Привет, предложение для следующей статьи - Всё то же самое можно сделать через hibernate search, без logstash и вендорлока на elastic/lucene/open search. При чем можно индексировать только нужные поля.
Наблюдал совершенно обратную ситуацию с RPS. Только не на синтетическом кейсе, а готовом приложении. Натив это не только старт, но и меньше cpu/mem. Точных цифр не помню, но условно 15-30% там было. Вместо micronaut был quarkus
Вы правда не читали то на что это написали? Попробуйте ещё раз.
Но мысль понятна, если мы пишем фреймворк, для работы с железом, куда прикрутится сторонними разработчиками любое железо, то надо тестировать его на реальном железе(а нам как бы интерфейсы Линукс тестировать) и виртуализировать железо.
Как бы тут сказать. Все веб программирование научилось виртуализироваться, разработчики чипов - эмулирует работу на fpga. И только в эмбеддед - будь добр припаять провода. Только хардкор.
А давайте я вам еще усложню задачу... В этом фрэймворке есть эдак 600 интегрированных модулей которые тестируются параллельно.
Ну например интеграция с Oracle, DB2, MySql, Postgrees, Keycloak, AWS, K8S, Camel и еще очень длинный список.... Ну все вместе потащим куда то на железо? Только виртуализация, образы, контейнеры и где приходит embedded - наступает боль...
Они свое "реальное железо" в облако github завезли? Установили в стойки датацентров и тестируют? :)
https://github.com/OP-TEE/optee_os/blob/master/.github/workflows/ci.yml
Те же контейнеры или qemu
Может я что-то не понимаю, но давайте это попробуем наложить на кейс:
Есть github и проект в нем. Который раз в день собирается где то в облаке гитхаба.
JOB-а качает ubuntu-latest на armv7 где у нас даже нет даже близко SPI/I2C/UART/etc
Нам надо поднять эти интерфейсы виртуально(либо запилить свой образ где они есть), чтобы наше приложение через read/write/ioctl могло с ним работать.
Привязать под эти виртуальные интерфесы какие то виртуальные девайсы, которые читают что им пишут и шлют ответ
Соответственно in/out должен соответствовать ожидаемому
Боюсь не прирываний, ни тем более доступа к CPU и регистрам у нас тут нет.
Сейчас же я вижу исключительно возможность тестировать на конкретном "железе" и никак иначе
Проблема в том, что мне надо гонять фреймворк, драйвера к устройствам по CI в облаке. Т.е там может быть даже не ARM. Надо виртуально создать те же SPI/Serial интерфейсы и виртуальные устройства к ним. И как то оттестировать все.
Так что регистры сразу мимо. Виртуализация шин и устройств на Линукс нужна.
Ну то есть код лежит а github и тестируется job-ами на gitthub, где не ARM не подключенных устройств нету.
Сколько не думал, так и не смог решить задачу - допустим у нас есть embedded linux. Под капотом есть arm и какая то обвязка. А как собственно оттестировать работу с этой обвязкой? Эмулировать i2c, spi, serial, а поверх прикрутить виртуальные устройства вместо реальных датчиков и устройств.
Примерно как mook server для http.
Все, что выше тестируется легко. А вот уровень железных интерфейсов - боль. Не поделитесь?
>>> Использовать вручную native-image не хотелось
Я про то, что не надо заводить кваркус, надо завести Грааль. Кваркус то раз в день по CI в натив собирается.
>> Очень интересная ссылка
А вот пример по работе со всеми интерфейсами и разными датчиками.
Если осилите написать какую то документацию на это(мне пока лениво) то добавлю в quarkus repo
Del