Привет, хабравчанин!

В этой заметке речь пойдет о Plotti.co — адски простом в использовании инструменте, который делает ровно одну вещь, но делает её быстро и хорошо. Речь пойдет об онлайн-рисовании графиков и их обновлении в реальном времени.

Создание живых графиков на лету, как мне кажется, не является той задачей, для решения которой нужно сперва прочесть 10 страниц документации, заплатить за подписку по $20 в месяц, а иногда — и то, и другое сразу. Так нельзя. Не в 2016 году.

image

В Plotti.co клиентская часть — это SVG-изображение, которое подписывается по EventSource на источник данных от сервера, и обновляет график в соответствии с ними. Интегрируется она в страницу элементарно:

<object data="http://plotti.co/U0N5G5FQigwC/plot.svg" type="image/svg+xml"></object>


Да, это всё. Здесь U0N5G5FQigwC — это хеш картинки. Чтобы картинка обновилась во всех браузерах, в которых она сейчас открыта, необходимо просто послать GET-запрос по соответствующему адресу. Например,

wget "http://plotti.co/U0N5G5FQigwC?d=1.5,3.6,7.8mbps" -O /dev/null



Значения переменных передаются в параметре d и разделяются запятыми. Максимальное число переменных (и, соответственно, линий на графике) — 9; цвет каждого из них фиксирован. Если хочется получить линию какого-то конкретного цвета, можно пропустить нужное число переменных перед ней (например, вот так: http://plotti.co/U0N5G5FQigwC?d=,,,,,,1.0).

Проект сделан по принципу «eat your dogfood», так что прямо на заглавной можно посмотреть график текущей загрузки процессора сервера, на котором он крутится. Данные скармливаются в график с помощью нехитрого шелл-скрипта:

#!/bin/sh
while true; do
wget -O /dev/null -q http://plotti.co/lock/plottycocpu?d=`mpstat -P ALL 1 1 | awk '/Average:/ && $2 ~ /[0-9]/ {print $3}' | sort -r -g | xargs | sed s/\ /,/g`\%cpuload
done


P.S. Проект был написан за два дня силами одного человека и запущен на ARM-сервере от Scaleway за $3 в месяц, и при этом почти пережил нашествие юзеров с Hacker News позавчера ночью (до 4 тыс одновременных коннектов). Gevent FTW! Дальнейшие исследования показали, что использовать инстанс Xeon у Vultr за $5 в месяц более оправданно.
P.P.S. Проект опенсорсный, приветствуются баг репорты и пулл реквесты!
P.P.P.S. Мопед не мой, а хорошего человека; я пока в основном только свечку держал.

Комментарии (15)


  1. Dreyk
    17.03.2016 13:31
    +2

    Можно было бы описать хоть немножко технических деталей реализации


    1. rumith
      17.03.2016 14:01
      +1

      Сервер — крошечное приложение на Python/gevent/Flask, пока вообще ничего сложного. Сейчас работаем над балансировкой нагрузки между ядрами и серверами, мб станет поинтереснее. Все сорсы на Гитхабе.


      1. Dreyk
        17.03.2016 14:04

        да, я уже глянул гитхаб. в основном интересовал тот самый EventSource и яваскрипты внутри SVG, о которых вас также спросили ниже.
        Собственно сам backend на фласке не является краеугольным камнем приложения и может быть заменен на любой язык


  1. mannaro
    17.03.2016 13:35

    Интересный сервис. Хоть я и понимаю, что это бесплатный микросервис, но хотелось бы иметь какой-то URL для инициализации. Типа plotti/init/publicCode?secret=secretCode&size=20 дабы можно было привязываться не по IP, а по секретному коду. Обновлять в таком случае график можно было бы по адресу plotti/update/secretCode?d=... а смотреть по plotti/publicCode
    Ну и параметр, который отвечает за длину графика (size=20) по-моему просто необходим.

    Да и d= можно немного доработать. Зачем все впихивать в одну переменную, если их можно принимать несколько? red=1.0&blue=2.0.


    1. rumith
      17.03.2016 14:04

      Про секретный код — отличное предложение, спасибо. Сейчас заведу issue в трекере.

      А насчет d= — чего не сделаешь ради компактности :-). Но мы подумаем; для графиков с одной-двумя линиями так действительно удобнее.


      1. mannaro
        17.03.2016 15:26

        Я уже завел. Сразу после того, как отписался тут.


  1. ayurtaykin
    17.03.2016 13:49

    Я в шоке, а как оно работает? Это web socket? JavaScript получает данные с сервера и "дорисовывает" SVG ?


    1. rumith
      17.03.2016 13:59
      +1

      Это не websocket, это EventSource. Остальное верно, при этом весь JavaScript упакован внутрь SVG.


  1. el777
    17.03.2016 14:24
    +1

    Чем продиктован выбор EventSource?
    Что будет с данными при перезагрузке сервера?


    1. rumith
      17.03.2016 14:29

      Данные на сервере не хранятся вообще. Сервер работает только в режиме ретрансляции.
      EventSource — потому что удобно, само реконнектится и т.п., а обратная связь не нужна.


      1. el777
        17.03.2016 14:36
        +2

        Имхо, EventSource хуже поддерживается и имеет больше проблем по сравнению с WS.


  1. savostin
    17.03.2016 15:06

    Подождите, так это любой сможет посылать данные в мой svg?


    1. rumith
      17.03.2016 15:07
      +2

      Есть возможность залочить свой svg и сделать привязку фидера к IP адресу. Пока что ничего более правильного не реализовано, т.к. задача стояла сделать proof of concept, а не сразу создавать большой продукт с кучей возможностей.


      1. savostin
        17.03.2016 16:08

        Ну, раздел с прайсами успели сделать ;)


        1. rumith
          17.03.2016 16:24
          +1

          Велика мудрость — накидать примерные пожелания по донейтам :-)