Микросервисы в MODX

Всем привет! Продолжая свою тематику использования других ЯП в modx стало интересно насколько будет просто или не просто интегрировать микросервис, который использует отличную от MySQL бд в админку modx, и на удивление оказалось что это проще, чем могло показаться.
Под катом мой репозитории, демо, а также рассуждения по этому поводу.


Задача:


Сделать микросервис, который по http запросу запускает браузер, ищет элемент на странице и делает его скриншот, создает sqlite базу данных и записывает туда данные, также имеет возможность отдавать эти данные. Необходимо сделать интерфейс взаимодействия в админке на modx, чтобы он не отличался от нативных интерфейсов.
Задачу придумал из головы для того, чтобы взять то, с чем php не справится физически

Определяем технологии:
1) Микросервис пишем на GO, потому что на нем быстрее и надежнее, чем на nodejs
GitHub
Бинарник
2) Разворачивать будем в докере, потому что микросервис не должен быть доступен извне, к нему должно иметь возможность достучаться только приложение на modx
3) Используем MODX 3 потому что интересно посмотреть что там ребята наделали и modExtra чтобы быстро развернуть стартовый интерфейс

P.s. modExtra не работал под modx 3 по этому пришлось сделать фикс, github, учтите это, если кто решит повторить эксперимент

Контейнеризируем:


Файл docker-compose выглядит следующим образом.
Тут стоит подробнее остановится на докерфайле микросервиса:
FROM orendat/go:latest

# Устанавливаем зависимости для хрома
RUN apk update && apk add --no-cache bash \
    alsa-lib \
    at-spi2-atk \
    atk \
    cairo \
    cups-libs \
    dbus-libs \
    eudev-libs \
    expat \
    git \
    flac \
    gdk-pixbuf \
    glib \
    libgcc \
    libjpeg-turbo \
    libpng \
    libwebp \
    libx11 \
    libxcomposite \
    libxdamage \
    libxext \
    libxfixes \
    tzdata \
    libexif \
    udev \
    xvfb \
    zlib-dev \
    chromium \
    chromium-chromedriver \
    && apk add wqy-zenhei --update-cache --repository http://nl.alpinelinux.org/alpine/edge/testing --allow-untrusted \
    && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && rm -rf /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

# Клонируем исходники микросервиса напрямую с гита, и их же собираем
RUN git clone https://github.com/pavel-one/GoElementScreenshot.git ./
RUN go build -o bin cmd/main.go
Т.е. мы не храним бинарник в проекте вообще, мы его собираем прямо в контейнере, там же и храним, если внеслись какие то изменения, все, что нам надо — пересобрать контейнер, это удобно для масштабирования, кубера и подобных штук.
Также, если мы хотим сохранять базу данных микросервиса, можно в volumes прокинуть файл db.sqllite3
volumes:
      - ./db.sqlite3:/usr/src/app/db.sqlite3
как то так, в противном случае при каждом docker-compose down микросервис будет очищать свою БД и начинать «с нуля»
Ну а если мы хотим чтобы микросервис был доступен для всех, в отрыве от modx, нам достаточно прокинуть network или port
ports:
      - 8080:8080

Интегрируем в MODX


Окей, мы запустили MODX в контейнере и WS в контейнере, давайте подумаем о том, как их связать и тут у меня было два варианта решения:

XPDO:

Честно сказать это был бы самый грамотный вариант решения вопроса
1) Расширяем базовую модель XPDO, делаем новый класс RemoteXPDOSimpleObject
2) Переписываем методы кастинга и получения свойств модели, в которых получаем их по API
3) Прописываем в общей карте схемы по аналогии с обычными моделями XPDO, подобную практику не раз реализовывали в laravel и eloquent

Плюсы:
  • Можем использовать абсолютно все API modx'a, даже не замечая, что получение данных идет с удаленного сервиса
  • Полная интеграция с getResource и подобными расширениями, которые используют API modx'a
Минусы:
  • pdoTools использует api modx'a только чтобы сбилдить запрос в базу данных, и то, не во всех случаях, интеграции с pdoTools мы все равно не добьемся
Изначально мной было принято решение идти этим путем, я вновь окунулся в исходники XPDO, и лучше бы я этого не делал… Из моего исследования родился этот PR с самым минимальным рефакторингом который можно было бы представить, и он вылился в более чем 1000 строк измененного кода… Я не однократно говорил что создание modx 3 надо было начинать не с отказа от ExtJS и даже не с попыткой соблюсти PSR, его надо было начинать с уничтожения xpdo
В общем данный путь уперся бы в огромное количество работы по переписыванию всего, что только можно с минимальным выхлопом, т.к. мы все равно не добились бы рабочего pdoPage например.

Используем процессоры!

Огорчившись что «нормально» все равно не получится интегрироваться я вспомнил про такую замечательную вещь — как процессоры:

Плюсы:
  • Мы можем полноценно использовать систему прав modx'a и иметь доступ ко всему его контексту
  • Неплохая интеграция в систему, процессоры легко запускать и использовать в любой точке системы
Минусы:
  • Для обработки данных от микросервиса где то на фронте сайта (например) нам придется писать свой сниппет, пусть и будет он написан полностью на API modx'a
Из этого получилось минимальных три процессора:
  1. Create
  2. GetList
  3. Get
А также базовый для них класс с клиентом:
тык

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

Что со скоростью?


А с ней предполагаемо все отлично. Go — быстрый компилируемый язык, время ответа микросервиса составляет 6мс, это в десять раз быстрее чем ответил бы modx даже без выборки из базы данных, так что вы врятли увидите хоть какую то задержку

Для чего эта заметка?


Я не знаю. После последней заметки про MODX на GO у меня оставалось чувство недосказанности, множество людей предлагали начать с выноса каких то частей MODX'a на GO а только потом уже писать все с нуля, мне было интересно это попробовать, по результату могу сказать что он не однозначный, полноценно из modx вынести не получится ни один модуль, слишком он легаси, слишком не расширяемый и не поворотливый, но что-то разработать на другом ЯП для modx'a можно
Мне хотелось попрощаться, новое руководство в лице Николая ясно дало понять что меня не хотят больше видеть в сообществе (забанив без объяснения причин в чате), спасибо сообществу за интересные 7 лет опыта, это было прекрасно, всем желаю не стоять на месте, развиваться хотя бы для того, чтобы взглянуть на старые вещи под другим углом

Репозитории


Проект
Микросервис

Ну а потыкать все самому можно на открытом

Демо

modx_admin
X5NasAOm
Ну и прямая ссылка на компонент на демо сайте
Pavel Zarubin
22 ноября 2022, 16:19
modx.pro
2
633
+19
Поблагодарить автора Отправить деньги

Комментарии: 8

vectorserver
22 ноября 2022, 18:29
0
Круто! Но SVG похоже не хавает)


Я делал такой-же для одной CRM только на NODEJS Puppeteer, принцип такой же, задача была пройтись по сайтам и отсечь те которые не адоптированы к мобилкам + отчет от lighthouse_viewer



    Pavel Zarubin
    22 ноября 2022, 20:22
    +1
    Круто! Но SVG похоже не хавает)
    Да не было задачи сделать работающую на 100% штуку, была задача сделать штуку, с которой не справится php) На весь эксперемент был всего лишь один вечер)

    Puppeteer
    Очень много работал с пуппетером и его аналогами в ноде, go в этом плане сильно удобнее т.к. может группировать процессы на отдельные потоки, может например запустить браузер и держать его запущенным а каждую вкладку обрабатывать отдельным потоком, убивается поток — убивается вкладка и никаких memory leak
    Василий Наумкин
    23 ноября 2022, 05:49
    +3
    Я не однократно говорил что создание modx 3 надо было начинать не с отказа от ExtJS и даже не с попыткой соблюсти PSR, его надо было начинать с уничтожения xpdo
    Самый главный-преглавный архитектор не разрешает. Он же по совместительству и автор xPDO.

    Из моего исследования родился этот PR с самым минимальным рефакторингом который можно было бы представить, и он вылился в более чем 1000 строк измененного кода…
    Никто не примет, никому такое не надо.
      Максим
      23 ноября 2022, 07:32
      0
      У меня не работает. Нажимаю «добавить», заполняю поля, после «сохранения» ничего не происходит. Пробовал разные сайты, разные селекторы, результат один — нулевой.
        Максим
        23 ноября 2022, 07:35
        0
        Видимо определенные сайты разрешено скриншотить… я пробовал www.kinopoisk.ru/, github.com
          Максим
          23 ноября 2022, 10:22
          0
          Возможно из-за ограничения времени процесса. Если картинка большая или html какой-то сложный и требует долгой обработки, тогда ничего не происходит. Если взять какой-нибудь логотип сверху, то работает…
            Pavel Zarubin
            23 ноября 2022, 17:04
            +1
            Судя по всему так и есть, решилось бы выносом процесса скриншота в отдельный поток, и дальнейшую обработку «статусов обработки» но это уже немного выходит за рамки эксперемента на один вечер) Но за тестирование спаисбо)
        Николай Савин
        27 ноября 2022, 10:05
        +3
        Призываю всех участников беседы проявить сдержанность и дружелюбие (кому что проще) и далее обсуждать только тему поста без перехода на личности.
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          8