LINUX.ORG.RU

Сообщения byko3y

 

О чудесном сервере OpenResty

Наткнулся на статью:
https://habr.com/ru/post/321864/ - OpenResty: превращаем NGINX в полноценный сервер приложений

У меня сразу возникло два вопроса:

  • Мне одному кажется, что автора статьи - бородатый школьник, который сам не разбирается в теме статьи, и половину онной кидает гнилые понты про «я с пелёнок пишу хайлоад»?
  • В чем преимущество OpenResty над альтернативными решениями?

Для тех, кто не в курсе, кратко расскажу про OpenResty. Кому-то в Taobao стукнуло в голову, что будет очень хорошим решением взять nginx и засунуть в него LuaJIT. Именно «в него», а не «к нему». Так родился модуль Lua для nginx, на основе которого был сделан OpenResty и еще пару подобных проектов. Nginx однопоточен, LuaJIT однопоточен, вот они как бы в event-driven модели должны хорошо согласовываться. Питон/php/node.js тоже однопоточны, но пожирнее и помедленнее будут. С тех пор OpenResty распространился в основном по китаю, хоть и в остальной мир потихоньку проникает.
Мотивация создателей мне ясна: берем самый быстрый веб-сервер (пусть и неполноценный), берем самый быстрый скриптовый язык, которым на 2011 года действительно был именно Lua c его LuaJIT, скрещиваем их вместе, говорим волшебные слова - получаем замечательный полноценный веб-сервер. Правда, уже на момент 2017 года дистанция между V8 и LuaJIT неумолимо сокращалась, и сейчас они имеют похожую производительность выполнения кода.

Возникает еще один вопрос: а при чем тут nginx вообще? Смысл создания nginx заключался в том, чтобы сделать невидимую тонкую прослойку между системными вызовами ядра ОС, а посему функций у nginx может быть немного: статический контент, кэш, трансляция между двумя протоколами. На загрузках меньше 1000 запросов в секунду разница между nginx и каким-нибудь apache уже становится ничтожная. О чем думали создатели, засовывая в поток nginx скриптовый язык со сборкой мусора?

PS:

Если у вас, допустим, кодовая база на Perl, и вы не Booking, вы не найдёте перловых программистов. Потому что их нет, их всех забрали, а учить их долго и сложно

Палю годноту: Booking набирает кодеров без знания перла для работы с перлом. Так что если кто мечтает писать на перле - имейте в виду.

 , , ,

byko3y ()

Объектная модель питона

- Сколько нужно архитекторов, чтобы создать язык программирования?
- Сто. Один будет писать язык, а 99 - говорить, что могут сделать лучше.

Так скажем, я решил вспомнить обсуждение по теме треда: Generics в Python или помогите победить mypy

Да, наркоманский питон захватывает мир, и с этим нужно что-то делать. Нет, я не намерен делать питон 4 - я вижу свет в конце тоннеля в рамках третьей версии. Но мне нужна ваша помощь: какие фундаментальные фичи, по-вашему, в питоне вообще не нужны, а какие - должны быть переработаны?

Прежде всего, я хотел бы вспомнить про RPython ( https://rpython.readthedocs.io/en/latest/rpython.html ).
Смысл особенностей языка прост - поддержка вывода типов. В частности, из языка убраны динамические определения классов и функций, динамическая типизация переменных, глобальные переменные стали константами, функции-генераторы транслируются в классы-итераторы и потеряли большую часть своих фич. У RPython есть большой минус - эти его ограничения сильно раздувают код, затрудняют писание и читание.
Итак, мои соображения:

1. Множественное наследование. Его нет даже на уровне C-функций в реализации питона и API расширений. «Но как же интерфейсы?» - возразите вы. Интерфейсы в C++ и Java нужны в роли объявления протоколов вызова методов объекта с целью последующей статической проверки этих протоколов при компиляции, а также для формирования таблиц методов, которые можно использовать независимо от объекта во время выполнения. Эти роли полностью потеряны в питоне, потому нет никакого оправдания их существованию. Мне нравится то, как сделаны интерфейсы в Go - это очень похоже на питоновые ABC: https://www.python.org/dev/peps/pep-3119

2. Генераторы - зло. Это прямо-таки запущенный случай GoTo, когда выполнение не просто бесконтрольно прыгает по коду - оно прыгает по стэкам. Особенно лютая дичь происходит, когда генераторы пересекаются с менеджерами контекста (привет PEP 567). В треде, скорее всего, опишу веселости реализации генераторов в PyPy/RPython. В питоне есть общая тенденция запутывать приложение в тесный клубок связанных изменяемых состояний, что не дает возможности параллелить и оптимизировать выполнение программы, а генераторы - вишенка на этом торте.

3. Изменение классов для существующих экземпляров объектов. Не, я понимаю, что класс в питоне объявляется во время выполнения. Но, блин, зачем в него совать изменяемые переменные? Зачем в старые объекты добавлять новые методы? Причем, попрошу обратить внимание на то, как нужно нагибаться раком для того, чтобы добавить аналогичные методы в сам объект, а не в класс - для этого нужны types.MethodType, function.__get__, functools.partial, и так далее. Методы в питоне вообще понадобились по простой причине - гвидо не придумал других способов сделать короткие имена функций (чтобы не было gtk_button_set_focus_on_click), поскольку не ясно, как выбирать из кучи похожих функций с коротким именем нужную под этот конкретный объект. Так в питоне появились len, iter, next, isinstance, slice, dict, dir, str, repr, hash, type - сейчас это обертки над соответствующими методами классов с подчеркиваниями в имени, а когда-то встроенные простые типы не являлись классами и работали только через эти функции. Так-то, я не вижу особой разницы между записью method(object) и object.method - особенно если method является статичной функцией, которой, в общем-то, все равно, какой первый аргумент (self) принимать.

Вот. Прошу дополнять. Да, я знаю, что у питона основные проблемы две: отсутствие статической типизации и многопоточности - но это черезчур абстрактные требования. К тому же, Javascript безо всяких типизаций достиг производительности Java, при том, что жавамакакам постоянно приходится гнуться под язык, а JS-кодеры испытывают удовольствие от говнокодинга.

 , ,

byko3y ()

Многопоточный питон, PEP 554

Как вы могли знать, уже два года идет вялотекущий перевод питона на поддержку независимых интерпретаторов в одном процессе.

https://github.com/ericsnowcurrently/multi-core-python
https://www.python.org/dev/peps/pep-0554/

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

Теперь главный вопрос: зачем? PEP 554 предлагает обращаться за помощью к каналам, как в Go, но:
- каналы как средство взаимодействия потоков убоги даже в Go;
- в питоне уже есть multiprocessing, который по сути и есть развитая идея каналов с возможностью прокинуть в обе стороны вызов функции и запрос атрибутов объекта, вплоть до итераторов, но не более того.

Для людей, которые уже готовы отвечать «ну дык есть же многопроцессы, есть форк на никсах - вот и используйте их», напомню, что реализация форка процесса на уровне ОС-и в действительности мало помогает многоПРОЦЕССовости питона - машем ручкой сборщику мусора, который передергивает счетчики ссылок:
https://instagram-engineering.com/dismissing-python-garbage-collection-at-ins...

>>> import os, sys, gc
>>> len(gc.get_objects())
6888
Это весьма эффективная модель сборки мусора... если у вас ровно один процесс.

Допустим, у нас уже есть несколько независимых потоков интерпретатора. Логичное желание - придумать какие-то эффективные модели взаимодействия интерпретаторов, которыми кто-то захочет пользоваться.
Примитивные ячейки данных (вроде многопоточного bytearray или других настраиваемых структур) довольно бесполезны, потому что мы же пользуемся питоном для того, чтобы взмыть вверх по абстракциям. Если же мы надумаем передать через подобнюу структуру хотя бы элементарную функцию, вроде

def hello():
    return "hello world"
то окажется, что объект строки и объект функции сидят в другом интерпретаторе, а сборщик мусора принципиально не умеет работать более чем в одном потоке, потому просачивание объекта из одного потока в другой вызывает катастрофические последствия.

Можно замутить атомарные операции на питоне, которые будет писать сам пользователь для описания превращений сложных структур, но есть проблема с побочными эффектами и гарантией потокобезопасности, потому что:
- любая функция в питоне использует все вышестоящие контексты, а также имеются замыкания, которые могут использовать свои собственные контексты;
- в CPython довольно сложно понять, работает ли функция с побочными эффектами или без онны. Речь не только про код на питоне, но еще и про код на си.

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

В итоге, на текущий момент, многопоточная разработка сводится к настройке внешних по отношению к питону потоков, как то сделано в NumPy, а потому разработать отзывчивый GUI на одном питоне не получится, например.

Кто-то видит свет в конце тонеля? Или же это предсмертные видения?

 ,

byko3y ()

Ищу интерсную работу Asm, C, Python

Я осознаю, что Python+ML или Django сейчас дают хороший доход и есть много вакансий. Проработав много лет над скучным проектом Delphi+Firebird у меня нет больше желания работать просто ради денег, вплоть до того, что я бы занялся неким общественно ценным проектом забесплатно.
Опыт: GSoC на C и GTK; разработка ARM-контроллера электропривода на C; многопоточные приложения Win32 API (не только VCL) и SQL (firebird). Говорю/слушаю/пишу/читаю english, примерно A2-B1, хуже всего говорю, хорошо слушаю. Хорошо знаком с экспериментальной орг. химей. Малообщителен, но имею склонности к решению сложных проблем, в частности, отладка. Из более поверхностных знаний Django, JS, Haskell, SQLite, OpenGL, Maemo, разработка модулей ядра Linux, настройка Linux серверов (bind, apache, nginx, postgresql).
Местоположение - глубинка, потому скорее всего удаленное взаимодействие.

 , , ,

byko3y ()

Испортил жесткий диск магнитом

Понравилось, как неодимовый магнит магнитится ко всему. Жесткому диску это, по-видимому, ни разу не понравилось.

# ddrescue /dev/sdc2 /dev/null
rescued:   157181 MB,  errsize:       0 B,  current rate:   75169 kB/s
   ipos:   157181 MB,   errors:       0,    average rate:   93942 kB/s
   opos:   157181 MB,     time from last successful read:       0 s
Finished
# ddrescue /dev/sdc3 /dev/null
rescued:     2716 MB,  errsize:    325 kB,  current rate:     7948 B/s
   ipos:     2716 MB,   errors:       2,    average rate:   15346 kB/s
   opos:     2716 MB,     time from last successful read:       0 s
Interrupted by user
# ddrescue -i 3000M /dev/sdc3 /dev/null
rescued:    983552 B,  errsize:       0 B,  current rate:    51765 B/s
   ipos:        3 GB,   errors:       0,    average rate:    51765 B/s
   opos:        3 GB,     time from last successful read:       0 s
Interrupted by user
# ddrescue -b 1024 -i 4000M /dev/sdc3 /dev/null
rescued:    456704 B,  errsize:   68608 B,  current rate:     8617 B/s
   ipos:        4 GB,   errors:       1,    average rate:     8617 B/s
   opos:        4 GB,     time from last successful read:       0 s
Interrupted by user
#ddrescue -b 1024 -i 60000M /dev/sdc3 /dev/null
rescued:     1358 kB,  errsize:    215 kB,  current rate:    11355 B/s
   ipos:    60001 MB,   errors:       2,    average rate:    12132 B/s
   opos:    60001 MB,     time from last successful read:       0 s
Interrupted by user
Могу запостить смарт, но там всё довольно очевидно, разве что значение Spin Up Time странное, но я не знаю, как его интерпретировать:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   200   200   051    Pre-fail  Always       -       411
  3 Spin_Up_Time            0x0027   154   151   021    Pre-fail  Always       -       1266
PS: я тут че подумал: может обратной стороной магнита поводить, а то я только одной стороной водил, он наверное намагнитился у шпинделя, и при приближении к центру диска отказывает.

byko3y ()

RSS подписка на новые темы