Wednesday, June 24, 2009

Параметры мобильного телефона используя wurfl

Для того чтобы определить параметры мобильного телефона можно использовать 2 пути:
  • определение свойств на основе мобильного профайла возвращенного в заголовках запроса (CC/PP);
  • определение на основе данных переданных в качестве UserAgent.
Первый случай дает возможность сделав несколько запросов на профайл и изменения в нем по протоколу CC/PP получить полные официальные данные об устройстве, но этот случай имеет несколько недостатков, указанный в профайле ресурс может быть недоступен и мы терем время на эти запросы.

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

Принцип работы с базой wurfl:
  1. найти максимально похоже имя user agent по xpath пути:"/wurfl/devices/device/@user_agent. (В первой версии искалось полное соответствие.)
  2. определить идентификатор этого описания: "/wurfl/devices/device[@user_agent='UserAgent']/@id"
  3. попытаться получить описание нужного нам свойства используя: "/wurfl/devices/device[@id='идентификатор']/group[@id='markup']/capability[@name='html_wi_oma_xhtmlmp_1_0']/@value" . markup - имя группы свойств, html_wi_oma_xhtmlmp_1_0 - свойство.
  4. Если получить не удалось получаем идентификатор подобного устройства: "/wurfl/devices/device[@id='идентификатор']/@fall_back".
  5. Если получить описание устройства не удается через fall_back мы всегда попадем на описание generic устройства, у которого значение всех свойств равно false.
Ссылки:

Wednesday, June 17, 2009

Патчи к gtkhtml

Описание моих патчей к gtkhtml:
  • Get rid of deprecated libgnomecanvas Удалена зависимость от libgnomecanvas (полностью удален bonobo компонент, не устанавливаемый по умолчанию в систему) и переписан код конструирования панелей использовавших bonobo (теперь код использует только функции gtk+). Доступно в версии 3.26.
  • Удаление использования libgnome Замена на использование GtkBuilder для генерации меню и автоматический поиск каталога с тестами. Доступно в версии 3.27.3.
  • Поддержка data URI Добавляет поддержку datauri, также:
  1. исправляет код формирования url на основе относительного и базового url страницы с которой вызывается запрос (теперь в);
  2. добавлена автоматическая замена содержимого при получении, если при вызове получения данных ожидается html, но была получена картинка, автоматически формируется html с ссылкой на эту картинку;
  3. добавлено два вызова для gtkhtmlstream установки базовой страницы и content type для конкретного потока, ранее эти параметры устанавливались для всего документа и он мог отобразиться не корректно.
  • Использование GtkBuilder вместо libglade. Заменяет устаревший(deprecated) libglade на более универсальный код использующий GtkBuilder. (3.07.2009 - применено в основной ветви, будет доступно в следующем релизе).
  • Поддержка cookies - включает поддержку cookies при установленном libsoup версии > 2.26, включается только в тестовом приложении не устанавливаемом в систему. Доступно в версии 3.27.3.
P.S.: поддержка этих изменений в skybrowser я не добавил.
  1. Код со всеми моими изменениями.
  2. Официальный репозиторий.

Friday, June 5, 2009

timeouts in merle

Добавил в мою ветвь кода merle возможность работы с timeout.
  1. В функцию connect новый параметр Options, передаваемый в функцию gen_server:start_link . Этот параметр позволяет установить timeout и включить режим отладки:
  • Options ::= [{timeout, Timeout} | {debug, [Flag]}]
  • Flag ::= trace | log | {logfile, File} | statistics | debug(debug == log && statistics)
  1. В getkeylist(Key, Timeout) добавлен параметр максимального ожидания ответа, предыдущий вариант тоже остался, его поведения также можно эмулировать - указав значение 0
  2. Функция setlist теперь ожидает установки только время указанное как значение времени кеширования (гарантия что. если время кэширования было превышено, сохранение не произойдет). При значении 0 поведение сохраняется, как было до изменения.
Эти изменения позволяют снизить количество одновреммено запущеных запросов к merle во время повышенной нагрузки на систему временем timeout.

Monday, May 25, 2009

Изменил мою ветвь с Merle.

Вернул все файлы которые удалил в своей версии merle. Это нужно для большей совместимости с основной веткой, и возможности обновления с нее с последующим вливанием изменений, если получиться в основную ветвь кода.

Чтобы отключить использование gen_server2 - нужно только переименовать все gen_server2 -> gen_server.

Friday, May 22, 2009

Повышение надежности системы

Повышение надежности предыдущей схемы (используя nginx).

В предыдущей схему существует один потенциально ненадежный элемент backend сервер. При его сбое система через некоторое время утрачивает возможность отрабатывать запросы, так как время кэширования на memcahed заканчивается и все запросы начинают идти на этот сервер. В результате система не может выдать никакого контента пока он не будет перезапущен. Чтобы этого избежать можно дать возможность frontend возвращать данные с просроченным сроком давности, реализовать это на уровне memcached усложняет способ работы с ним:
  • по умолчанию, если закончилось время хранения контент удаляется;
  • и при смене поведения усложняется алгоритм работы с ним из frontend.
В результате наиболее простым методом, если используется в качестве frontend nginx, можно разрешить ему при сбоях использовать собственный кэш (опция proxy_cache_use_stale). Пример:

proxy_cache_path /var/tmp/nginx/cache levels=1:2 keys_zone=one:10m inactive=20m max_size=500m;

server {
listen 80;

location / {
if ( $args = "" ){

set $memcached_key "$uri";
memcached_pass 127.0.0.1:11211;
error_page 404 502 503 504 = @backend;
add_header "Content-Type" "text/html; charset=UTF-8";
add_header "Cache-Control" "max-age=15";
}

proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_buffers 8 32k;

proxy_cache_key "$scheme://$host$uri$is_args$args:";
proxy_cache one;
proxy_cache_min_uses 1;
proxy_cache_valid 200 30s;
proxy_cache_use_stale error timeout http_500 http_502 http_503;

}

location @backend {
proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_buffers 8 32k;

proxy_cache_key "$scheme://$host$uri$is_args$args:";
proxy_cache one;
proxy_cache_min_uses 1;
proxy_cache_valid 200 30s;
proxy_cache_use_stale error timeout http_500 http_502 http_503;
}
...............
В данном случае frontend не обязательно слабое звено - его можно продублировать с меньшими затратами по сравнению с дублированием backend + slaveDB.

Thursday, May 21, 2009

Код корректного перезапуска merle

При использование кода связи с memcached возможен случай когда соединение с memcached по каким-то причинам потеряно, например: рестарт memcached.
  • В данном случае возможен случай когда выполнить вызов не удается, но пересоединение не получается (закрытие (disconnect) сообщает - что закрывать нечего, а открытие (connect) сообщает - что уже есть соединение). В данном случае нужно убить это псевдо-рабочее соединение и запустить наново.
  • Другой случай когда соединяться не с кем - тогда метод connect просто выходит, не вызывая исключение, что очень плохо, так как не понятно, что произошло с системой - чтобы отловить эту ситуацию нужно разрешить посылку сигнала о завершении потока и ожидать получение этого сообщения.
Пример кода:

%%use with restart
try_with_restart(LU, F) ->
try
F()
catch
Sub : Reson ->
debug_log(LU, "Start procedure restart connect:~p~n",[{Sub,erlang:get_stacktrace(),Reson}]),
spawn(fun() ->
process_flag(trap_exit, true),
Connect = merle:connect(?MEMCACHED_HOST,?MEMCACHED_PORT),
case Connect of
{error, {already_started, Client}} ->
debug_log(LU, "try kill client status:~p~n",[Connect]),
exit(Client,kill);
Value ->
debug_log(LU, "Some other error:~p~n",[Value])
end,
receive
{'EXIT', Pid, Why} ->
debug_log(LU, "Me killed~p~n", [{Pid, Why}])
end
end),
undefined
end.

Примечание:
  1. F - функция обращающаяся к merle;
  2. debug_log() - вывод в логи отладочной информации.

Sunday, May 17, 2009

merle совместимый с nginx

Выложил коды проектов используемых мною с некоторыми изменениях в них.

Изменения в коде merle (memcached erlang interface) нацелено на совместимость с другими языками программирования, в частности возможность получения сохраненного контента из nginx.

Стандартный код использует binary_to_term для сохранения контента в результате при попытке получить контент из memcahed из других программ, ожидающих возврат обычной строки, в начале контента невозможно так как появляются служебные данные erlang.

В код добавлены функции сохранения как строка merle:setlist( url, time, content), и получения контента в виде строки merle:getkeylist (url). Также удалено использование нестандартного gen_server. Удален только для упрощения поддержки кода, так как усовершенствования по очередям сообщений в проекте были не нужны.

В результате этих изменений удалось организовать систему когда frontend server(использовался nginx) мог не запрашивая backend получить сразу данные из кэша, также получилось использовать как общих кэш и для php.

Остальные функции постарался оставить без изменений их поведения и формата сохраняемых ими данных(term_to_binary), измения заключаются в переносе функций преобразования term_to_binary(getkey) и binary_to_list (getkeylist) из вызовов gen_server.

В erlyweb изменены:
  • опции компиляции по умолчанию, теперь поведение подобно поведению make, когда компилируются только измененные файлы;
  • добавлена обработка исключение при рендеренге компонентов встроенных в основную страницу (вместо него при ошибке выдается указание, что компонент отработал с ошибкой), исключение при отработке основной страницы не отлавливается и передается при ошибке дальше, его нужно отлавливать внутри этой страницы самостоятельно;
  • также, добавлена поддержка использования прописных букв в пути к каталогам с компонентами(ранее использовалось преобразование всех букв к строчным).