суббота, 26 марта 2011 г.

Субботний вечер пропаганды маргинальных технологий: Статистический анализ с помощью clojure и incanter

Начну из далека. Все прекрасно знают, что Java код компилируется в платформа независимый java bytecode. Sun'ики этого не планировали, но, так же как и для CLR, появились альтернативные языки, компилируемые под JVM. Зачастую это порты других известных языков: Jython (Python), JRuby (Ruby), Kawa (Scheme). Они пользуются небольшой популярностью по очевидной причине, люди предпочитают использовать не порт, а настоящий язык. Но есть языки разработанные специально для JVM. Например Groovy, солянка Ruby и Java, заполучил своё место под солнцем как скриптовый язык, часто используется, как основа более гибких конфигураций, нежели статический xml и вроде веб на нём тоже делают. Ещё есть Scala, мельтипарадигменный язык, который совмещает в себе огромную кучу фич из ООП и ФП. Мне он не очень нравится перегруженностью синтаксиса, но он набирает популярность как замена Java. Но сегодня я хотел бы поговорить о Clojure - это функциональный язык, диалект великого Lisp'а. Ах, нет, я хотел обмануть, про замечательный язык clojure я не стану рассказывать детально в этой статье, лучший способ с ним познакомиться это одноименный раздел на сайте Алекса Отта. Там же есть постоянно обновляющаяся вводная статья написанная Алексом для журнала fprog.

Я участвую в проекте по обработке данных. Предыдущая версия использовала MS Sql Server для своей работы, поэтому анализ работы системы сделать было достаточно просто, можно было обойтись и простым t-sql скриптом или, если нужно было графическое представление, то можно было использовать Reporting services. Сейчас же, для того компонента, которым я занимаюсь, никакие СУБД не используются, поэтому какие-то выводы можно делать исключительно по логам. Поэтому даже был сделан отдельный структурированный лог в csv формате обо всех важных событиях, произошедших в системе. К примеру, к нам приходит много файлов, поэтому для каждого из этих фалов, этот лог содержит упрощённо 3 записи: файл найден, файл отправлен на обработку, файл обработан. Как то у Ярослава возникла идея попробовать язык R, чтобы нарисовать какие-нибудь интересные аналитические графики. Меня идея заинтересовала, я скачал книгу и впал в ступор. В общем и целом, язык этот мне не понравился (можно сказать не осилил:)). Но месяц назад в очередном порыве изучения clojure, у Алекса наткнулся на упоминания о проекте incanter. Лучше всего его описали сами авторы:

Incanter is a Clojure-based, R-like platform for statistical computing and graphics.

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

понедельник, 7 марта 2011 г.

Две стороны одной медали: удобство разработки

Хотел немного подробнее раскрыть упомянутый в предыдущем посте антипаттерн "Immutable Class", изобретение которого принадлежит моей клавиатуре. В данном конкретном случая, это была попытка в Java реализовать Immutable object. И тут возникла проблема, которая всегда актуальна в спорах "динамическая типизация vs статическая типизация". Т.е. с одной стороны можно сделать конечный код (который использует этот класс) более простым, с другой стороны мы получаем ошибки, которые, как правильно в исходном посте заметил Андрей не находятся компилятором. И это действительно произошло, у людей были проблемы с модификацией этого класса, из за чего он и был наречён immutable. Хотел бы более развёрнуто описать почему я так решил, вернее почему мне кажется, что ответ на это вопрос не так однозначен. В самом исходном посте одну из причин я уже указывал, это наследования с огромным количеством переопределенных методов. Тут хотел рассмотреть вопрос удобства изменения только этого класса. Комментарии и в особенности критика приветствуются.

воскресенье, 6 марта 2011 г.

О поиске простого решения или как я писал JobStore для Quartz

Java очень хорошо известна своим разнообразием различных Open Source frameworks, одни ребята из Apache наверно несколько десятков сгенерировали. Причём всегда есть много альтернатив (к сожалению, зачастую все равно выбрать нечего :))). Но есть планировщик задач Quartz, которому нет альтернативы, почти стандарт, так сказать. Причём с архитектурной точки зрения он довольно прост и хорош. У нас есть Scheduler в котором мы регистрируем Trigger'ы и Job'ы и связи между ними, таким образом каждый триггер может активировать одну или несколько работ.

Данная библиотека одна из ключевых в одном из наших подпроектов. Важный вопрос как всегда это persistence. Т.е. возможны следующие случаи к примеру:

  • Если триггер должен сработать только несколько раз. То после рестарта приложения Scheduler должен знать об этом и не активировать его.
  • Если у нас есть триггер, который должен срабатывать каждый час, но спустя, например, 59 минут наше приложение упало. То когда его перезапустили, этот триггер должен сработать через минуту, а не через час.

Это вопрос в Quartz так же решён. Есть интерфейс JobStore, к которому обращается Scheduler за всеми нужными данными и он должен обеспечивать сохранность данных. По умолчанию существуют две реализации RAM и JDBC. Как нетрудно догадаться, RAM никакой сохранности не обеспечивает, но JDBC по сути должно хватить всем, так как почти любая СУБД к вашим услугам. К сожалению для нас это не так, мы не используем СУБД. Поэтому пришлось реализовывать JobStore самостоятельно. И вот тут, тот, кто также успел сходить по ссылке на api JobStore, мог ужаснуться, так как JobStore - это интерфейс наверно на полсотни методов. Поэтому под катом, моя история, как я пытался малой кровью реализовать этого бегемота для наших нужд :)