Когда питоновские скрипты приобретают какую-то готовую форму, и ими хочется поделиться с другими, возникает вопрос: как это правильно и красиво сделать?
Стандартом для распространения программ на Python является Python Package Index, своего рода центральный Python-репозиторий. О процессе публикации много написано, покажу, как это делается, на своём примере.
14 марта 2011 г.
7 марта 2011 г.
Реанимация данных
Жена с дочкой используют внешний USB-винт для хранения видео и всего такого. На днях прикупил новый, стал копировать данные со старого, и — бац! — I/O error! Битые сектора, они же бэд-блоки.
В итоге не удалось скопировать 4 видеофайла. Тут на помощь приходит старая добрая утилитка ddrescue — при ошибке ввода-вывода продолжает копировать посекторно, пропуская плохие участки, в итоге удаётся бóльшую часть данных вытащить; позволяет копировать как целое устройство, так и отдельный файл. Видео спасти получилось, благо небольшая доля мусора внутри файла не мешает его воспроизводить.
К сожалению, ddrescue не позволяет копировать целые директории рекурсивно. Тогда я написал простой скрипт на Python, rddr (Recursive DDRescue), копирующий каталог целиком с помощью того же ddrescue.
Но этот эпизод с винтом меня смутил — ведь есть же SMART, почему Ubuntu мне не сказал о непригодном состоянии диска? Оказалось, что состояние его "хорошее", но есть несколько плохих секторов. Есть у SMART такой атрибут, показывающий количество секторов, ожидающих замены из специальной дисковой зоны "хороших" секторов, причём замена происходит при попытке записи, а не чтения. Теперь на помощь приходит программа badblocks — она позволяет прогонять тесты чтения/записи по всему устройству. Тесты записи на винт заняли около одиннадцати часов, данные при этом затёрлись. 19 секторов из 20 восстановились из резервной области.
Вердикт: винчестер можно использовать для некритичных данных, видео хранить вполне годится.
P.S. Прекрасное руководство для восстановления данных с помощью Linux можно здесь почитать.
В итоге не удалось скопировать 4 видеофайла. Тут на помощь приходит старая добрая утилитка ddrescue — при ошибке ввода-вывода продолжает копировать посекторно, пропуская плохие участки, в итоге удаётся бóльшую часть данных вытащить; позволяет копировать как целое устройство, так и отдельный файл. Видео спасти получилось, благо небольшая доля мусора внутри файла не мешает его воспроизводить.
К сожалению, ddrescue не позволяет копировать целые директории рекурсивно. Тогда я написал простой скрипт на Python, rddr (Recursive DDRescue), копирующий каталог целиком с помощью того же ddrescue.
Но этот эпизод с винтом меня смутил — ведь есть же SMART, почему Ubuntu мне не сказал о непригодном состоянии диска? Оказалось, что состояние его "хорошее", но есть несколько плохих секторов. Есть у SMART такой атрибут, показывающий количество секторов, ожидающих замены из специальной дисковой зоны "хороших" секторов, причём замена происходит при попытке записи, а не чтения. Теперь на помощь приходит программа badblocks — она позволяет прогонять тесты чтения/записи по всему устройству. Тесты записи на винт заняли около одиннадцати часов, данные при этом затёрлись. 19 секторов из 20 восстановились из резервной области.
Вердикт: винчестер можно использовать для некритичных данных, видео хранить вполне годится.
P.S. Прекрасное руководство для восстановления данных с помощью Linux можно здесь почитать.
4 марта 2011 г.
Скоро выйдет Django 1.3
3 марта вышел кандидат в релизы Django 1.3. Я не вытерпел и полюбовался на внушительный список изменений будущей версии.
2 марта 2011 г.
Волшебная кнопка
Несколько раз я сталкивался с тем, что запущенная в линуксе программа начинает отжирать всю доступную память, система сваливается в штопор, и закрыть виновницу удаётся с большим трудом... Простой пример для теста — откройте XML файл в несколько мегабайт в Firefox. ;)
Уже гораздо позже я узнал, что есть т.н. "волшебная кнопка" — "бесполезная" клавиша SysRq (она делит место жительства с PrintScreen). Это единственная прямая связь с ядром линукса, работающая всегда (конечно, если работает и ядро). Тест из первого абзаца проходится с помощью SysRq+Alt+f — вызывается обработчик ситуации нехватки памяти, который и завершает самый "тяжёлый" процесс. Из любимого ещё убиение X-сервера — SysRq+Alt+k.
Уже гораздо позже я узнал, что есть т.н. "волшебная кнопка" — "бесполезная" клавиша SysRq (она делит место жительства с PrintScreen). Это единственная прямая связь с ядром линукса, работающая всегда (конечно, если работает и ядро). Тест из первого абзаца проходится с помощью SysRq+Alt+f — вызывается обработчик ситуации нехватки памяти, который и завершает самый "тяжёлый" процесс. Из любимого ещё убиение X-сервера — SysRq+Alt+k.
Статический анализ кода в 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.
Подписаться на:
Сообщения (Atom)