Несколько раз я сталкивался с тем, что запущенная в линуксе программа начинает отжирать всю доступную память, система сваливается в штопор, и закрыть виновницу удаётся с большим трудом... Простой пример для теста — откройте XML файл в несколько мегабайт в Firefox. ;)
Уже гораздо позже я узнал, что есть т.н. "волшебная кнопка" — "бесполезная" клавиша SysRq (она делит место жительства с PrintScreen). Это единственная прямая связь с ядром линукса, работающая всегда (конечно, если работает и ядро). Тест из первого абзаца проходится с помощью SysRq+Alt+f — вызывается обработчик ситуации нехватки памяти, который и завершает самый "тяжёлый" процесс. Из любимого ещё убиение X-сервера — SysRq+Alt+k.
2 марта 2011 г.
Статический анализ кода в Python
В статье на Хабре наткнулся на упоминание статических анализаторов кода для Python. Инструмент этот очень полезен при регулярном его использовании. Немножко подробнее расскажу о pep8, pylint и pyflakes.
Угодить pylint весьма сложно, порой он ошибается — к счастью, настройки достаточно гибкие.
На мой взгляд, золотая середина — pyflakes, поначалу можно использовать и pep8, дабы привить соблюдение стиля.
Бонус для пользователей Vim — вызов pyflakes или pylint после каждого сохранения редактируемого файла, сообщения об ошибках помещаются в окошко "quickfix":
pep8
Этот анализатор проверяет соответствие кода знаменитому PEP 8 — руководству по стилю кода Python. В больших и не очень командах хорошая штука, ибо "Readability counts"!pylint
Самый придирчивый анализатор из всех трёх, хотя стиль кода проверяет немножко иначе, чем pep8 — акцент на "дурно пахнущем" и неоптимальном коде, выдаёт и предложения о рефакторинге. Бонусная опция — генерация UML-диаграмм с помощью команды pyreverse.Угодить pylint весьма сложно, порой он ошибается — к счастью, настройки достаточно гибкие.
pyflakes
В отличие от pylint, проверяет только на логические ошибки в программе, стиль не учитывает.На мой взгляд, золотая середина — pyflakes, поначалу можно использовать и pep8, дабы привить соблюдение стиля.
Бонус для пользователей Vim — вызов pyflakes или pylint после каждого сохранения редактируемого файла, сообщения об ошибках помещаются в окошко "quickfix":
command Pylint :call Pylint()
function! Pylint()
setlocal makeprg=(echo\ '[%]';\ pylint\ %)
setlocal efm=%+P[%f],%t:\ %#%l:%m
silent make
cwindow
endfunction
command Pyflakes :call Pyflakes()
function! Pyflakes()
let tmpfile = tempname()
execute "w" tmpfile
execute "set makeprg=(pyflakes\\ " . tmpfile . "\\\\\\|sed\\ s@" . tmpfile ."@%@)"
silent make
cwindow
endfunction
autocmd BufWrite *.{py} :call Pyflakes()
25 февраля 2011 г.
Обработка ссылок mailto в Google Chrome
Наконец нашёл решение давней несуразности: в отличие от Firefox, линуксовый Google Chrome при попытке открыть почтовую ссылку (протокола "mailto") запускает почтовую программу, а мне нужен Gmail. Замечательный superuser.com подсказал, что в Ubuntu для этого достаточно установить пакет desktop-webmail (плюс к этому я выбрал Desktop Webmail в настройках Preferred Applications/Mail Reader — возможно, это необязательно).
22 февраля 2011 г.
Репликация и устойчивое хэширование в memcached
Memcached работает просто и быстро, как электровеник, и не поддерживает репликации, которая может понадобиться при горизонтальном масштабировании серверов memcached.
Есть как минимум два варианта решения этой задачи. Первый используется для репликации мастер-мастер и не зависит от языка программирования — repcached, патч к memcached, добавляющий репликацию между серверами. (Инструкция по установке.) Из минусов — устанавливать придётся, скорее всего, из исходников и поддерживается не самая последняя версия memcached (примерно полуторагодовалой давности).
Другой способ специфичен для PHP (впрочем, наверняка есть схожие решения и для других языков). Модуль php5-memcache позволяет реализовать подобие репликации с помощью хранения каждого ключа на N серверах. В случае, если один из серверов падает, ключ будет храниться на оставшемся и каком-то N+1 сервере. С помощью этого модуля можно хранить и сессии с избыточностью. Выдержка из readme:
Для большинства приложений такой надёжности достаточно.
Вдобавок этот модуль использует т.н. "устойчивое хэширование" ("consistent hashing"). Вкратце, этот алгоритм позволяет привязывать ключи к определённым серверам memcached и при удалении/добавлении серверов бóльшая часть ключей останется привязана к тем же серверам. Таким образом, для распределения нагрузки без использования репликации достаточно встроенных средств php5-memcache.
Для Python такую функциональность предоставляет модуль hash_ring.
Есть как минимум два варианта решения этой задачи. Первый используется для репликации мастер-мастер и не зависит от языка программирования — repcached, патч к memcached, добавляющий репликацию между серверами. (Инструкция по установке.) Из минусов — устанавливать придётся, скорее всего, из исходников и поддерживается не самая последняя версия memcached (примерно полуторагодовалой давности).
Другой способ специфичен для PHP (впрочем, наверняка есть схожие решения и для других языков). Модуль php5-memcache позволяет реализовать подобие репликации с помощью хранения каждого ключа на N серверах. В случае, если один из серверов падает, ключ будет храниться на оставшемся и каком-то N+1 сервере. С помощью этого модуля можно хранить и сессии с избыточностью. Выдержка из readme:
# When enabled the client sends requests to N servers in parallel, resulting in
# a somewhat crude reduncancy or mirroring, suitable when used as a session
# storage.
#
# If data integrity is of greater importance a real replicating memcached
# backend such as "repcached" (http://sourceforge.net/projects/repcached/) is
# recommended
memcache.redundancy = # default 1
memcache.session_redundancy = # default 2 Для большинства приложений такой надёжности достаточно.
Вдобавок этот модуль использует т.н. "устойчивое хэширование" ("consistent hashing"). Вкратце, этот алгоритм позволяет привязывать ключи к определённым серверам memcached и при удалении/добавлении серверов бóльшая часть ключей останется привязана к тем же серверам. Таким образом, для распределения нагрузки без использования репликации достаточно встроенных средств php5-memcache.
Для Python такую функциональность предоставляет модуль hash_ring.
18 февраля 2011 г.
Новое в PHP
Господин Ilia Alshanetsky (судя по всему, выходец из СССР) опубликовал прекрасную презентацию о малоизвестных фичах в PHP, в частности, PHP 5.3: PDF (3 МБ). В свою очередь хочу упомянуть о появлении в PHP 5.3 анонимных функций, с помощью которых можно реализовывать и замыкания (closures). Не так удобно, как в других языках, но сам факт радует.
9 февраля 2011 г.
Чёрная магия Ruby
На работе понадобилось поменять пару вещей в Redmine — написан он на Ruby on Rails. Случилось то, что так давно откладывал — я познакомился с Ruby и RoR.
Ruby произвёл неоднозначное впечатление большого хака, из которого к тому же торчат уши зубодробительного Perl. Но хак этот эффективный и в умелых руках работает со страшной силой. К RoR эти слова применимы в квадрате — это ещё бóльшая чёрная магия. Японское происхождение частично объясняет странность Ruby.
Избранные места из документации Ruby:
Лично мне ближе элегантность Python, замешанная на дзене. ;)
Ruby произвёл неоднозначное впечатление большого хака, из которого к тому же торчат уши зубодробительного Perl. Но хак этот эффективный и в умелых руках работает со страшной силой. К RoR эти слова применимы в квадрате — это ещё бóльшая чёрная магия. Японское происхождение частично объясняет странность Ruby.
Избранные места из документации Ruby:
- В Ruby всё — объекты. Даже числа. Чего стоит, например, такой код:
5.times { |i| print i, ' ' }Этот кусочек иллюстрирует ещё одну странную, но мощную фишку — передача кусков кода в виде аргументов функции. Похоже на lambda-функции в Python, но мощнее и применяется повсеместно. - При записи числа допустима, например, следующая форма:
a = 1_000_000
Чтобы, значит, читабельность кода увеличить. - Ruby вообще любит использовать ASCII-таблицу по максимуму. Функция проверки валидности может называться
valid?, а сортировка массива "in place" —sort!. - Как и многие языки, в Ruby объекты могут наследоваться лишь от одного родителя. Но можно включать в класс код из других модулей, при этом их функции становятся методами данного класса — это ж настоящий monkey patching!
- Определение класса может состоять из несколько кусков. Т.е. мы начали определять класс A, потом пошло определение класса B, потом мы опять продолжили определить класс A. На практике это означает, что можно переопределить поведение даже базовых классов, того же String. Вот это действительно monkey patching.
- И ещё для Ruby написано самое странное руководство из тех, что я встречал.
Лично мне ближе элегантность Python, замешанная на дзене. ;)
10 декабря 2010 г.
Новый старый PNG
Оказывается, формат PNG не так уж и прост. Среди прочего он позволяет эффективно сжимать градиентную заливку внутри картинки, отсюда вывод — если требуется на градиентный фон что-то наложить, эффективнее будет сделать фон отдельной картинкой, а сверху наложить другую с объектами переднего плана и прозрачным фоном.
Есть несколько утилит для оптимизации размера PNG, одна из лучших открытых — OptiPNG, есть удобные обёртки под Windows, Mac и Linux. Но ещё лучше по степени сжатия — бесплатная утилитка PNGOUT.
Есть несколько утилит для оптимизации размера PNG, одна из лучших открытых — OptiPNG, есть удобные обёртки под Windows, Mac и Linux. Но ещё лучше по степени сжатия — бесплатная утилитка PNGOUT.
Подписаться на:
Сообщения (Atom)