воскресенье, 30 октября 2011 г.

SO и Habr - поверхностное сравнение

Довелось недавно поучаствовать в подготовке небольшого перевода на Habr и немного в его поддержке после публикации. В процессе как-то придумалось сравнение со SO. Вот смотрите:
  1. Рейтинг. SO: единая постоянная метрика основанная на качестве контента. Habr: двухкомпонентная система: рейтинг основанный на контенте, но убывающий по времени и карма основанная на "личных качествах", постоянна по времени.
  2. Право публикации. SO: постоянное и неотъемлемое. Habr: даётся по итогам попрошайничества зависит от кармы.
  3. Возможность голосовать за. SO: всегда имеется. Habr: зависит от кармы.
  4. Возможность голосовать против. SO: имеется всегда, но за счёт своего рейтинга. Habr: зависит от кармы.
  5. Продолжительность голосования по топику. SO: не ограничена. Habr: ограничена по врмени.
  6. Оценки комментариев. SO только +, незначительное влияние на рейтинг. Habr: + или -, заметное влияние на рейтинг.
Вот подумалось, вроде 6 мелочей. Но ведь очевидна "заточка" одного под аккумуляцию полезного контента, а другого под массивные срачи и популяризацию кадров вроде alizar'а.

PS А ещё SO хоть и не ограничивает по рейтингу возможность публикации, зато существенно ограничивает возможности по созданию энтропии. Вот я например уже давно мечтаю о 1,5к рейтинга, чтобы наконец уметь создавать новые тэги а то на говнище, в котором я копаюсь постоянно даже тэга не находится.

суббота, 15 октября 2011 г.

Опыт работы с Lift: часть 1

После доклада на ScalaSPB образовалась подборка материалов, которыми грех не воспользоваться. Заодно включу в них то, что никак не вписывалось в доклад: примеры с кодом и философские рассуждения. И начну я пожалуй с наиболее простого и короткого кусочка, а именно опыта общения с Lift.

(Тут нужна небольшая вводная: речь идёт об опыте разработки REST сервиса. Он во-первых заведует преобразованиями между domain model и схемой хранения данных. Во-вторых по ходу дела планирует и выполняет всякие дополнительные задачи вроде отправки оповещений на почту или шаринга контента в facebook.)

Итак, от Lift'a используется практически два модуля. Это поддержка REST-сервисов и сериализация case классов в JSON (что однако тянет с собой всю инфраструктуру работы с HTTP). В работе с ними было три эпизода, которые представляют интерес. Ниже привожу первый из них.

Нестандартная авторизация

Первая проблема, которую пришлось решить это не совсем стандартная схема авторизации, используемая в нашем приложении. А именно: все экспортируемые методы делятся на два класса: приватные и публичные. Приватные защищаются на уровне файрвола от внешнего доступа и к ним на уровне приложения доступ свободный. Публичные доступны всем и соответственно на них висит авторизация. Авторизация не простая а по токену, добавленному одновременно в куку и параметр запроса. Это не что иное как издревле известный метод борьбы с CSRF. Придумать легко, а вот обучить Lift такому поведению потребовало немного нестандартного приёма.

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

Для того, чтобы под неё подстроиться была выбрана следующая стратегия:

  1. Помечать часть путей внутри сервиса, как требующие авторизации требуя для них определённую "волшебную" роль;
  2. Выполнять аутентификацию при наличии токенов путём присваивания текущему пользователю двух ролей: "волшебной" и роли с его идентификатором в качестве имени;
  3. Предоставлять нашему коду абстракцию над предыдущими двумя шагами вида "получить авторизованного для данного метода пользователя". Этот метод изящно реализовывался паттерн-матчингом над списком ролей :)

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

Ну а рассказ про замеченые проблемы с производительностью будет в следующем псто...