В прошлом месяце наши собственные Алекс Карл и Рон Нельсон посетили CED Tech Venture Conference, региональное сетевое мероприятие для стартапов и инвесторов из Северной Каролины.

Рон, наш директор по продажам и резидент-вундеркинд Mario Kart, также сделал короткую презентацию о быстром росте Adzerk за последний год.

Хотя я лично не присутствовал на конференции, некоторые программы, которые я написал, присутствовали. Это программное обеспечение, Панель показов, представляет собой одностраничное приложение (или SPA), демонстрирующее нашу технологию и некоторых наших клиентов. Алекс и Рон настроили его для работы на Macbook, подключенном к телевизору на нашем стенде.

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

Вот как это выглядело на конференции:

Вы также можете запустить клиентскую версию Dashboard, чтобы лучше понять, что она делает. Из соображений удобства панель инструментов была разработана специально для телевизора, на котором она была представлена ​​— она может отображаться неправильно на вашем экране.

В этом посте я поделюсь некоторыми инструментами, сервисами и практиками, лежащими в основе этого небольшого, но успешного приложения.

ИНФОРМАЦИОННОЕ ПРИЛОЖЕНИЕ

В начале прошлого месяца я проработал в Adzerk всего несколько дней, когда Dashboard стал потенциальным первым проектом. Tech Venture была не за горами, и проекты, подобные Dashboard, были успешными на предыдущих конференциях. Нам нужна была Dashboard, и нам нужна была быстро.

В частности, нам нужно было приложение, которое:

  • показывал реальные, производственные показатели и постоянно обновлялся
  • Алексу и Рону было бы легко настроить
  • вернуться к историческим данным во время сбоя Wi-Fi, возобновить работу с данными в реальном времени после восстановления подключения
  • было эстетично
  • может быть построен и испытан за 3 дня, вершины

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

ДЕНЬ 1: РЕШЕНИЯ, РЕШЕНИЯ…

Единственное, что я знал наверняка в начале первого дня, это место, где живут данные, которые я должен был показать, и это место было Datadog.

Мы счастливые и активные пользователи Datadog. Мы работаем с сотнями инстансов AWS EC2, и метрики — важная часть того, что делает возможным работу в нашем масштабе. Наши сервисы отправляют данные о событиях в Datadog, которые затем мы можем просматривать в режиме, близком к реальному времени, с помощью встроенных в браузер Datadog инструментов запросов и построения диаграмм.

Инструменты, которые Datadog предоставляет через свой веб-интерфейс для построения графиков и информационных панелей, феноменальны и близки к тому, что нам нужно для нашей собственной панели Impressions Dashboard. Тем не менее, нам было интересно показать что-то фирменное и более простое от Adzerk.

К счастью, в дополнение к информационной панели и инструментам запросов, Datadog имеет хороший HTTP API, который мы можем опрашивать с помощью метрического запроса. Затем мы могли бы использовать этот результат запроса в качестве значения для датчиков приборной панели. С нашими собственными сервисами, Datadog и Dashboard картина выглядит примерно так:

БОЛЬШЕ О ХОПЛОНЕ

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

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

Cadillac в данном случае — это Hoplon, фреймворк Clojure и ClojureScript для создания SPA, таких как наша Dashboard.

Помимо достоинств функционального программирования, которые дает Clojure, Hoplon также предлагает обработку HTML-разметки — как альтернативный синтаксис ClojureScript — который может помочь удовлетворить нашу амбициозную цель — поддерживать приложение дизайнером.

Объединение программы и разметки — это то, что спасает нас от теневого мира и открывает для нас проверенные временем инструменты абстракций черного ящика в контексте браузера.

Возможно, самым важным преимуществом Hoplon в случае с этим приложением, учитывая жесткие сроки, является возможность использования и модуляризации существующих элементов, таких как подключаемые модули jQuery и сетки, для рендеринга элементов интерфейса, таких как датчики и выполнение жидкостного позиционирования.

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

О, и Hoplon также рулит, потому что я сделал его (с Micha Niskin) и оттачивал его специально для SPA, подобных этому, в течение последних двух лет. Да, этот пост в блоге сфальсифицирован :-)

ДЕНЬ 2.0: РАЗРАБОТКА МАКЕТНЫХ ДАННЫХ

После установки лесов для проекта Hoplon я приступил к поиску деталей, которые мне понадобятся, чтобы сделать что-то эстетически приятное.

Из-за того, как работает Hoplon, меня совершенно не интересовали детали получения данных от Datadog для целей разработки интерфейса. У меня было довольно хорошее представление о том, что мне нужно, и о том, что Datadog поддержит мои потребности в данных.

Помочь мне не заботиться о Datadog мне помог Javelin, библиотека ClojureScript, принесенная Hoplon, которая четко отделяет презентацию от вычислений, используя модель потока данных, подобную электронной таблице.

Точно так же, как диаграмме в электронной таблице все равно, откуда взяты значения, из которых она получена, компоненты моего пользовательского интерфейса (UI) не будут заботиться о происхождении значений, которые они должны отображать. Процесс подделки данных и их получения по сети изолирован от процесса их отображения благодаря Javelin и модели электронных таблиц.

Как работает большинство фреймворков SPA, вы можете подумать, что это невозможно. Поверьте мне, это так.

Пользовательский интерфейс может отображать только значения, а не процессы. Как появились ценности, мы не знаем и не заботимся.

Первой частью, которую я искал, была структура сетки, чтобы упростить позиционирование элементов. Хотя в прошлом у меня были хорошие результаты с Zurb Foundation, в наши дни я предпочитаю Twitter Bootstrap, хотя бы потому, что в StackOverflow есть огромное присутствие Bootstrap, которое будет чрезвычайно полезно, когда я неизбежно застряну. .

Еще одним преимуществом Bootstrap является то, что он доступен в Hoplon Vendor, банке библиотек JavaScript и jQuery, упакованных для удобного использования проектами Hoplon. Мне нужно было только добавить загрузочный пакет Hoplon Vendor к набору зависимостей Maven моего проекта, и Bootstrap был в наличии, активы и все такое.

Интерактивная разработка с использованием Hoplon осуществляется в основном через «живую перезагрузку» — когда я сохранял файлы ClojureScript, HTML и CSS, приложение в моем браузере автоматически обновлялось.

Поскольку меня заботило только то, как приложение будет выглядеть на конкретном дисплее, который Рон и Алекс привезли на конференцию, я установил телевизор на своем столе, чтобы я мог разрабатывать прямо на нем, перезагружая по ходу дела:

ДЕНЬ 2.5: КОМПОНЕНТЫ

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

Как только я создал скелетный проект Hoplon/Bootstrap примерно на 2,5 дня, пришло время снова доказать это самому себе. Я начал искать какой-нибудь плагин «манометр».

Я попробовал gauge.js, jQuery gage и JustGage и остановился на JustGage, потому что мне больше всего понравилось, как он выглядит. JustGage красиво смотрелся на телевидении, потому что он использует SVG и анимацию, и это было явно то, что я не смог бы быстро состряпать самостоятельно. Использование его вместо альтернативы или использование моего собственного датчика не составляло труда, особенно с учетом моего нехватки времени.

API JustGage

Чтобы создать JustGage, сначала нужно написать небольшой HTML-заполнитель:

<div id="gauge" class="200x160px"></div>

Затем немного JavaScript:

var g = new JustGage({
    id: "gauge",
    value: 67,
    min: 0,
    max: 100,
    title: "Visitors"
  });

API JustGage типичен для библиотек элементов пользовательского интерфейса браузера в том смысле, что:

  • экземпляры создаются с помощью конструктора, в данном случае JustGage(), который принимает объект JavaScript из пар ключ/значение конфигурации.
  • конструктор принимает идентификатор узла HTML, к которому он должен добавить динамически сгенерированную разметку. Для JustGage в объекте конфигурации указывается ключ "id". Плагины jQuery обычно «привязываются» к объекту jQuery и работают с любыми выбранными элементами, которые он представляет.
  • методы экземпляра элемента обеспечивают изменение внутреннего состояния во время выполнения. Экземпляры JustGage поддерживают метод .refresh, который принимает новое значение для отображения.

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

Начнем с положительной ноты: приятно, что JustGage() принимает объект вместо позиционных параметров, учитывая, что в объекте конфигурации может быть дюжина или более возможных ключей.

Что менее приятно, так это то, что обязательным аргументом является id целевого элемента. Это похоже на жесткое кодирование указателя в качестве аргумента функции. Помимо того факта, что этот id находится в пространстве имен, отличном от пространства имен нашей программы JavaScript, способ работы DOM также только что установил временную зависимость между нашим экземпляром JustGage и DOM, потому что указанный нами элемент доступен только после того, как DOM загружен.

Итак, нам нужно использовать $(document).ready(...) jQuery для управления этой временной зависимостью, немедленно добавляя к нашему шаблону.

Наконец, чтобы обновить экземпляр JustGage после загрузки приложения, мы должны сохранить его дескриптор, чтобы мы могли вызывать его метод .refresh. С необходимостью обратного вызова круг путаницы замыкается. Добавление большего количества экземпляров и других типов элементов пользовательского интерфейса, которые необходимо обновлять аналогичным образом (и в определенных порядках), усложнит оркестрацию и отладку обратных вызовов по мере роста приложения.

Модульность с дефелем

К счастью, с Hoplon у нас есть инструменты, позволяющие абстрагироваться от деталей владения и эксплуатации экземпляров JustGage. Давайте поиграем с самым важным инструментом, идеей, что HTML можно рассматривать как Lisp, прежде чем мы применим его к JustGage.

HTML как ClojureScript

Hoplon предоставляет платформу, в которой миры JavaScript и HTML объединены. В Hoplon разметка и код выражаются одинаково — как программа. Например, рассмотрим следующий HTML:

<h1>Lisp is awesome!<h1>

Согласно обычной семантике браузера, этот фрагмент существует в статическом файле HTML, интерпретируется средством визуализации HTML браузера и становится доступным в DOM как объект HTMLHeadingElement после обработки файла HTML.

В Hoplon HTMLHeadingElement объектов можно создать следующим образом:

(h1 "Lisp is awesome!")

h1 в данном случае является функцией ClojureScript, и соглашения о ее вызовах соответствуют остальному языку ClojureScript. Вот более сложный пример, который также дает HTMLHeadingElement, но демонстрирует некоторые преимущества, присущие рассмотрению HTML как альтернативы Lisp:

(let [language "Lisp"
      adjective "awesome"]
  (h1 (str language " is " adjective "!")))

Функциональная HTML-композиция

Поскольку h1 и все другие конструкторы объектов DOM являются обычными функциями, мы можем создавать и компоновать разметку интересными способами. Рассмотрим этот фрагмент HTML:

<ol>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ol>

В Hoplon мы могли бы выразить это так:

(ol (li "first")
    (li "second")
    (li "third"))

Хотя синтаксически версия Hoplon немного более лаконична, реальная сила заключается в том, что, поскольку HTML — это язык программирования, мы можем устранить liдупликацию с помощью средств функционального программирования:

(ol (map li ["first" "second" "third"]))

Обратите внимание на две вещи:

  1. Функции конструктора DOM, такие как li, могут без проблем передаваться функциям более высокого порядка, таким как map
  2. Если функции-конструктору DOM, такой как ol, передается коллекция, она «склеивает» коллекцию со своими дочерними элементами.

Элементы — это функции

Возможно, мы часто создаем списки ol с кучей строк. Мы могли бы рассмотреть возможность создания функции:

(defn quicklist [& strs]
  (ol (map li strs)))

Теперь мы можем составить такие списки:

(quicklist "first" "second" "third")

Пользовательский элемент! Поскольку элементы являются функциями, и мы можем тривиально создавать именованные функции, мы можем так же тривиально создавать «пользовательские элементы», такие как quicklist здесь.

Вернуться к JustGage

Итак, что мне действительно нужно, так это «настраиваемый элемент» под названием gauge, который принимает некоторые параметры и который я мог бы использовать в разметке, как если бы он поставлялся с браузером. Вот как это выглядело, когда я закончил:

(defelem gauge [{:keys [value min max title label]
                 :or   {max 100}
                 :as   attrs}]
  (let [div-id     (str (gensym))
        elem-attrs (dissoc attrs :value :max :title :label)]
    (with-let [elem (div (assoc elem-attrs :id div-id))]
      (with-init!
        (let [params (js-obj "id" div-id, "max" max, "title" title, "label" label)
              gauge (js/JustGage. params)]
          (cell= (.refresh gauge value)))))))

Это промежуточный ClojureScript, и он также использует некоторые функции и макросы, характерные для Hoplon, поэтому не беспокойтесь, если он не имеет для вас полного смысла. Что следует отметить по этому поводу, включают в себя:

  • он использует defelem для определения функции gauge, которая принимает ряд атрибутов как attrs, используя деструктурирование карты ClojureScript.
  • он генерирует div со случайным именем, называемым (str (gensym)), чтобы указать экземпляру JustGage на
  • он создает экземпляр JustGage, передавая объект params, созданный с помощью js-obj, функции ClojureScript для создания общих объектов JavaScript.
  • cell= прикрепляет «ячейку формулы» Javelin к аргументу value. value здесь — «ячейка ввода», которая представляет собой ссылочный тип, похожий на Atom. Идея ячеек и cell= заключается в том, что выражения должны запускаться, когда любые зависимые ячейки изменяют значение. Здесь cell= используется для запуска выражения (.refresh gauge value) при каждом изменении значения value.

Датчик запросов

Имея под рукой обычный калибровочный элемент, я смог создать еще один пользовательский элемент, query-gauge. Идея с query-gauge заключалась в том, что я мог создавать датчики в разметке и передавать запрос Datadog для визуализации в виде строкового атрибута.

Внутри query-gage опрашивает наш сервер Clojure, который, в свою очередь, опрашивает API Datadog, который возвращает метрику обратно в датчик для отображения. Поскольку этот пост уже немного содержателен, я приберегу подробности для другого поста.

В итоге в файле index.html.hl я смог создать такие датчики:

<dash.query-gauge
  q="sum:eventserver.events.impression{*}"
  max="15000"
  title="Impressions"
  label="per second">
</dash.query-gauge>

ДЕНЬ 3: ПРОВЕРКА И ТЕСТИРОВАНИЕ

На самом деле я не делал ничего интересного в День 3, потому что День 2 был очень продуктивным! Мое время в основном уходило на настройку CSS и обеспечение работы кода в различных сценариях подключения. Днем я развернул приложение на машине в AWS и показал Алексу, как настроить его в Chrome.

ГРУППОВЫЕ ОБЪЯТИЯ

Этот пост был бесстыдной шумной игрой гоплонов, но я надеюсь, что, по крайней мере, он дал вам понять, насколько я взволнован гоплоном и тем потенциалом, который я вижу в нем. Я рекомендую вам попробовать краткий учебник на hoplon.io, чтобы убедиться в этом самостоятельно.

Если вам больше нравится YouTube, вас может заинтересовать доклад и демонстрация, которые я недавно провел для Clojure Toronto.

Есть вопрос или комментарий? Пишите мне в Твиттере, я @alandipert. Спасибо за чтение!

Эта запись была первоначально опубликована Аланом Дипертом в Техническом блоге Adzerk в октябре 2014 г. Вы можете узнать больше о Adzerk здесь.