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:
# 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:
  • В 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 написано самое странное руководство из тех, что я встречал.
В заключение можно ещё раз повторить: Ruby — очень эффективный инструмент в умелых руках. В неумелых он вносит хаос в код и мозг программиста.

Лично мне ближе элегантность Python, замешанная на дзене. ;)