Comments 14
Честно говоря, выглядит как портал в ад, похоже инструмент, который может помочь как-то зарефачить огромный Джанго-монолит. Но без каких-то реальных примеров вообще непонятно, что происходит, хотя может я просто не опытный джангист.
Спасибо. Согласен, путь именно туда...
Зарефакторить монстра - вряд ли получится, такой проект уже ничего не спасет :)
Эта технология поможет запустить в работу одни или несколько entpoints без рефакторинга.
На самом деле круто бы смотрелось продолжение статьи, где бы была взята какая-то конкретная ситуация из реального проекта и микрофича была бы переписана с помощью этого подхода. Если еще затащить при этом в статью пример с переписыванием на дефолтном нынче FastAPI рядом, чтобы понять, когда реально игра стоит свеч, то просто огонь.
Есть видео на немглийском на ютубе, где я именно это и делаю, плюс скрипт в репозитории, который вытаскивает файл для микрофичи ссылки в статье. Если с силами соберусь - превращу в статью. Суть в том, что мы создаем µ-сервис БЕЗ рефакторинга.
В другом докладе я переписываю микрофичу на Robyn и на Litestar. В репозитории смотреть в папках django-fastapi, django_and_litestar, django_and_robyn.
.
Лайк за детское творчество! :)
Так-то вещь интересная, но что, если рефакторить что-то сверхмассивное? Мутное, короче, дело, вряд ли часто юзабельное. Тут, скорее, надо самому долго тестить на левых прожектах, чтобы разобраться с этим чудо-юдом
@Ritoneet- Спасибо. Я рад, если стало интересно.
В статье пример про healthcare data lake из реальной жизни. 340 000 строк кода, я работал на проекте в роли приходящего seniour back-dev. Доклад про проект, и как я его пилил, для распиливания написал скрипт. Суть - выбираем один endpoint, натравливаем скрипт, получаем папку с одним файлом и кучей зависимости в подпапках. Добавляем только 1 строку в начале файла, импорт asgi, пихаем в контейнер запускаем через uvicorn. Повторить 412 раз.
Что получили - Монолит разбитый на микро куски, разумеется с кучей повторений в каждом куске. Каждая часть запускается отдельно. Никакого рефакторинга, кроме одной строки импорта. Разбили команду на 5 подкоманд, каждая свою пачку сервисов отслеживает если что падает - правит только свое. Стало быстрее: поиск и отладка ошибок и тестирование. Стало сильно напряжнее у девопсов. Придумали систему автоматизации создания репозитория, чтобы все было однотипно, и минимизировались ошибки при создании очередного суб репозитория µСервиса, а то глаз замыливается, если вручную создавать.
После 10 выделений в сервис стало понятно, какие файлы не надо копировать, они просто устанавливаются из репозитория монолита как pip install git+https://github.com/...
В итоге одну команду усилили и отправили на работу с этим ядром, которое импортируется в каждом сервисе. Все еще никакого рефакторинга.
Что сейчас. 19 человек ведут проект, 5 команд, каждая работает со своими кусками кода, и это минимальное количество файлов. центральный кусок очень медленно начали рефакторить, методом вывода некоторого микро кода в модули. Поскольку отщипываем от монолита во внешние репозитории, то сам монолит работает, как и работал. Сервисы монолита потихоньку отключали, поскольку на standalone все работает. Пока не были уверены, работало параллельно.
Из больших доработок - композитный генератор openAPI документации. По нему у меня доклад будет в этом году.
После внедрения, (месяца 3) - я уже стал не нужен, ребята сами справляются. В реальности им нужна была просто инструкция, что делать с монолитом, в котором они копошились, но не могли вынырнуть и посмотреть снаружи.
А вот мне после этого контракта стало сложно с обычными Django проектами работать: так и хочется начать µ-Djangо всюду впихнуть, потому, как это проще и быстрее. История про молоток и гвозди в полной мере про меня сейчас.
А я ведь всегда говорил, что Django не монстр, а всего 3 файла! А при желании, оказывается, и в один упаковать можно.
Мне не хватило описания практической задачи, когда такой подход может быть востребован. Рефакторинг монолита, кончно, зачёт, но очень специфичен. Вангую, что какие-нибудь лямбды в AWS с таким подходом можно писать.
На самом деле можно еще короче и лаконичнее. Все эти ленивые загрузки и лямбды на самом деле не нужны.
# settings.py
from django import urls
from django.http import HttpResponse
ALLOWED_HOSTS = ['127.0.0.1']
def home(_):
return HttpResponse('Hello world from mini Django!')
ROOT_URLCONF = (
urls.re_path(r'^$', home, name='home'),
)И
python -m django runserver --settings=settings
CMD [ "gunicorn", "--bind", "0.0.0.0:8000", "django.core.wsgi:get_wsgi_application()"]Верно. Ленивость запихана потому, что я хотел объявлять API в стиле "fastapi/flask". а так то все пихнуть в settings.py самое простое.
Я про эти части
wsgi = lambda args, *kwargs: get_wsgi_application()(*args, **kwargs)urlpatterns = SimpleLazyObject(lambda:[path('users/<pk>/', view.as_view()])
В обоих случаях ленивость не нужна.
Wsgi можно просто убрать вообще, и вызвать get_wsgi_application сразу из gunicorn.
А в urlpatterns ленивость в данном случае тоже не нужна. У него тут одно ограничение - он должен быть hashable( as_view без сайдэффектов), так что если список заменить на кортеж, все заработает без ленивости.
Однако, конечно если захочется админку завести, то тут ленивость придется добавить, но этот способ уже не подойдет.
Да, простите, душню. Понимаю что поздновато пришел, просто меня сама тема зацепила. изначально сел с квестом "а как бы сделать все покомпактнее", сделал, а потом решил погуглить кто еще таким занимался.
µDjango — технология создания асинхронных микросервисов