Спасибо большое, Узнал много нового, долго игрался с тасками, не обновлялся прайс, но почему-то когда создал новую подписку в ней все работало. Удалил старые и в новых все хорошо работает, очень интерсесно.
Можно в методе save() указать параметр update_fields в ф-ции set_price равный ('price', ) , в ф-ции set_comment равный ('comment', ). Тогда update в sql запросе не будет перезатирать все значения (можно чекнуть логи) объекта, а только указанные в update_fields. В данном случае эти 2 таски можно запустить параллельно.
Я просто взял этот кейс чтобы продемонстрировать проблему. В любом случае синглтон нужен , мы не можем всегда и везде это предусмотреть, особенно в немаленьких проектах
Спасибо за видосы, одна маленькая просьбочка! Перед выгрузкой видео ускоряй его слегка, потому что лично мне ютубовского 2х мало для просмотра твоего контента))
А зачем мы используем transaction.atomic? Ведь select_for_update уже блокирует объекты модели для использования другим воркером. Если сделать то же самое без transaction.atomic, что изменится?
а чем больше воркеров тем выше нагрузка на систему правильно? а если сам проект тяжелый? это же сильно по ресурсам бьет, есть ли альтернативные варианты выполнения тасков на такой случай?
Ну чем больше воркеров, тем больше запросов в базу, тем больше нагрузка на базу. Никак по-другому они систему не нагружают. Чтобы решить проблему нагрузки на базу лучше саму базу оптимизировать, добавить кеш, сделать еще read only базы и тд. Уменьшая количество Волкеров мы просто уменьшим производительность системы вцелом
Почему когда вы добавили транзакции и воркеры разобрали таски, один таск закончился намного раньше и не ждал 20+27 секунд? Куда делись эти самые sleep?
Можно зайти в контейнер и там уже писать команды,так image не будут создаваться ,а результат будет тот же, хотел тебе ещё задать вопрос - а почему не пользуешься тайпхинтами?
Да, согласен, через docker exec вроде так же работает. Тайпхинты - мы много спорили с коллегами по этому вопросу. Мое мнения что питон хорош тем, что это минималистичный, легко-читаемый язык. Если его превращать в Java по синтаксису, он никак не получит сильные стороны от Java, скорее получит его недостатки. в 99% случаев тайпхинты не нужны, когда и так очевидно что это за тип по названию. Но это зависит от проекта, конечно. Где-то они будут в тему. А вообще это спорный вопрос, кто-то прям за них всегда топит.
По поводу вашего вопроса. Как сделать так чтобы none не создавалось. Я в docker-compose после build вниз добавил image питона такой же как в Dockerfile. Вроде после этого перестает создаваться
Доброго времени суток! Благодарю за прекрасные курсы! Возник вопрос - если в Celery длительность очереди может быть большая, к примеру, час, то с этим возникают некоторые проблемы: - Если сервер перезагрузится по какой либо причине, таски исчезнуть, а значит и вся информация, которая должна была обновится, не будет обновляться. - Если я выключу сервер для обновления версии софта, то будет та же проблема - все таски слетят. Я чего-то не так понял и этих проблем не существует или для них уже есть решения?
Да, я думаю что проблемы будут скорее с тасками, которые уже запущены и в процессе выполнения на момент перезагрузки . Вроде была какая-то опция чтобы celery их перезапускал после перезагрузки, надо посмотреть в доке
Я не до конца понял необходимости добавления в запрос select_for_update? Зачем? Судя по доке, лочит строки в таблице, но мы вроде также используем менеджер transaction.atomic, который гарантирует, что операция будет выполнена полностью или не выполнена вовсе.... Можно пояснить подробнее про эту связку?
Это разные вещи. Atomic делает операцию атомарной, а select for update чтобы параллельные таски не пытались изменить объект , по тому что их изменения могут быть перезаписаны . На видео я опытным путем подтверждаю эту необходимость , если досмотреть до конца .
попробуй запускать команды в нужном контейнере через следующую команду: "docker-compose exec containe_name some_command_in_container" и в этом случае не будет создаваться новый контейнер
Привет. Ну в видео я показал два варианта: без трансакции и с ней. И то, как трансакция решает показанную проблему. Уровни изоляции они присутствуют в трансакциях. Без них не существуют. Тут же проблема что мы создали объект кода python , и он устарел , пока мы что-то делали , а потом мы его сохранили и он перезатер. Вообщем это немного другая ситуация.
Еще раз спасибо! Офигенный разбор! 👍👍👍 Правда, у меня косяк не воспроизводится, 😄 видимо, потому что я пошел путем апдейтов, а не сейвов: def set_price_from_service(service_instance_id): from .models import Subscription, Service time.sleep(10) service_instance = Service.objects.get(id=service_instance_id) queryset = service_instance.subscriptions.select_related('plan').only('plan__discount_percent', 'service_id') subscriptions = [] for i_subscription in queryset: new_price = service_instance.price - service_instance.price * i_subscription.plan.discount_percent / 100 i_subscription.price = new_price subscriptions.append(i_subscription) Subscription.objects.bulk_update(subscriptions, fields=['price']) @shared_task() def set_comment(service_instance_id): from .models import Subscription, Service service_instance = Service.objects.get(id=service_instance_id) queryset = service_instance.subscriptions.all() subscriptions = [] for i_subscription in queryset: i_subscription.comment = str(datetime.datetime.now()) subscriptions.append(i_subscription) time.sleep(20) Subscription.objects.bulk_update(subscriptions, fields=['comment'])
docker system prune -a -f, очистит все, кроме volumes, а посмотреть все можно чреез команду docker system df
Спасибо большое, помогли очистить 3 гб памяти
Спасибо! Total reclaimed space: 16.67GB
Ох уж эти параллельные таски, с ними надо максимально аккуратно работать.
Спасибо за еще одно чудесное видео!
В asyncio таски ведь не уходят ни в другой поток, ни в другой процесс, они в едином цикле событий, который в одном потоке 00:53
Чтобы избежать копипаста в docker-compose можно использовать якоря (&) и ссылки (
а можно пример?
Спасибо большое, Узнал много нового, долго игрался с тасками, не обновлялся прайс, но почему-то когда создал новую подписку в ней все работало. Удалил старые и в новых все хорошо работает, очень интерсесно.
как вариант, в таких не больших тасках, можно было бы просто использовать .save(update_fields=['comment'])
да, но поднятая проблема тоже актуальна, хотя ваше решение- снимает часть головной боли
Можно в методе save() указать параметр update_fields в ф-ции set_price равный ('price', ) , в ф-ции set_comment равный ('comment', ). Тогда update в sql запросе не будет перезатирать все значения (можно чекнуть логи) объекта, а только указанные в update_fields. В данном случае эти 2 таски можно запустить параллельно.
Я просто взял этот кейс чтобы продемонстрировать проблему. В любом случае синглтон нужен , мы не можем всегда и везде это предусмотреть, особенно в немаленьких проектах
Курс просто бомба !❤🔥
Вероятно образы с именем 'None' создаются, когда мы делаем ребилд. Имя затирается, а старый образ становится None
Уже жду следующий выпуск , как в сериале залип
Спасибо за видосы, одна маленькая просьбочка! Перед выгрузкой видео ускоряй его слегка, потому что лично мне ютубовского 2х мало для просмотра твоего контента))
Это чтобы оставалось время подумать! )
Удалить неиспользуемые образы: docker rmi $(docker images -q -f dangling=true)
Удалить контейнеры: docker rm $(docker ps -a -q -f status=exited)
Лучший канал по Django! Будут ли видосы про автоматизацию деплоя Django проекта через github actions + zero downtime deployment?
Может будут , да тема вцелом не сложная ..
Большое спасибо, крутые видосы
Столкнулся с проблемой, что из двух задач всегда выполнялась только одна. Никак кроме удаления Singleton решить не смог
А разве singletone не для этого?
Уроки по FastApi есть в планах ?
Пока нет. Может в следующем курсе
А зачем мы используем transaction.atomic? Ведь select_for_update уже блокирует объекты модели для использования другим воркером. Если сделать то же самое без transaction.atomic, что изменится?
Select for update не работает вне transaction
@@SeniorPomidorDeveloper спасибо большое что отвечаете всем нам
а чем больше воркеров тем выше нагрузка на систему правильно? а если сам проект тяжелый? это же сильно по ресурсам бьет, есть ли альтернативные варианты выполнения тасков на такой случай?
Ну чем больше воркеров, тем больше запросов в базу, тем больше нагрузка на базу. Никак по-другому они систему не нагружают. Чтобы решить проблему нагрузки на базу лучше саму базу оптимизировать, добавить кеш, сделать еще read only базы и тд. Уменьшая количество Волкеров мы просто уменьшим производительность системы вцелом
а где можно исходные коды посмотреть?
Тут github.com/chepe4pi/service_app
Сколько стоит воркеров делать в своих проектах?
Один. И дальше смотреть по нагрузке. Если очередь забивается и другие задачи долго ждут - значит другой, третий и тд.
Почему когда вы добавили транзакции и воркеры разобрали таски, один таск закончился намного раньше и не ждал 20+27 секунд? Куда делись эти самые sleep?
А в каком моменте видео это было?
@@SeniorPomidorDeveloperна 25:05. И потом ещё вы говорите: "видно, что одна таска отработала значительно быстрее"
Скорее всего на монтаже видео так неудачно подрезал. Там вроде дольше должен быть sleep , да
@@SeniorPomidorDeveloper понятно. Спасибо большое. Отлично объясняете.
@user-kn5ip9lr6r спасибо что смотрите!
Можно зайти в контейнер и там уже писать команды,так image не будут создаваться ,а результат будет тот же, хотел тебе ещё задать вопрос - а почему не пользуешься тайпхинтами?
Да, согласен, через docker exec вроде так же работает.
Тайпхинты - мы много спорили с коллегами по этому вопросу. Мое мнения что питон хорош тем, что это минималистичный, легко-читаемый язык. Если его превращать в Java по синтаксису, он никак не получит сильные стороны от Java, скорее получит его недостатки. в 99% случаев тайпхинты не нужны, когда и так очевидно что это за тип по названию.
Но это зависит от проекта, конечно. Где-то они будут в тему. А вообще это спорный вопрос, кто-то прям за них всегда топит.
Так много вкусного!
😁
По поводу вашего вопроса. Как сделать так чтобы none не создавалось. Я в docker-compose после build вниз добавил image питона такой же как в Dockerfile. Вроде после этого перестает создаваться
Доброго времени суток! Благодарю за прекрасные курсы!
Возник вопрос - если в Celery длительность очереди может быть большая, к примеру, час, то с этим возникают некоторые проблемы:
- Если сервер перезагрузится по какой либо причине, таски исчезнуть, а значит и вся информация, которая должна была обновится, не будет обновляться.
- Если я выключу сервер для обновления версии софта, то будет та же проблема - все таски слетят.
Я чего-то не так понял и этих проблем не существует или для них уже есть решения?
если я правильно понимаю, таски хранятся в Redis(БД) и селереи после перезапуска чекает редис.
Да, я думаю что проблемы будут скорее с тасками, которые уже запущены и в процессе выполнения на момент перезагрузки . Вроде была какая-то опция чтобы celery их перезапускал после перезагрузки, надо посмотреть в доке
@@BorisenkoV89Разве редис не очищается после перезагрузки системы?
Я не до конца понял необходимости добавления в запрос select_for_update? Зачем? Судя по доке, лочит строки в таблице, но мы вроде также используем менеджер transaction.atomic, который гарантирует, что операция будет выполнена полностью или не выполнена вовсе.... Можно пояснить подробнее про эту связку?
Это разные вещи. Atomic делает операцию атомарной, а select for update чтобы параллельные таски не пытались изменить объект , по тому что их изменения могут быть перезаписаны .
На видео я опытным путем подтверждаю эту необходимость , если досмотреть до конца .
попробуй запускать команды в нужном контейнере через следующую команду: "docker-compose exec containe_name some_command_in_container" и в этом случае не будет создаваться новый контейнер
спасибо!😎
спасибо!
Благодарю
Привет. Можно ли решить проблему параллелизма изменив уровень изоляции транзакций в самой бд? Например поставить repeatable read?
Привет. Ну в видео я показал два варианта: без трансакции и с ней. И то, как трансакция решает показанную проблему.
Уровни изоляции они присутствуют в трансакциях. Без них не существуют.
Тут же проблема что мы создали объект кода python , и он устарел , пока мы что-то делали , а потом мы его сохранили и он перезатер. Вообщем это немного другая ситуация.
👍
Еще раз спасибо! Офигенный разбор! 👍👍👍
Правда, у меня косяк не воспроизводится, 😄 видимо, потому что я пошел путем апдейтов, а не сейвов:
def set_price_from_service(service_instance_id):
from .models import Subscription, Service
time.sleep(10)
service_instance = Service.objects.get(id=service_instance_id)
queryset = service_instance.subscriptions.select_related('plan').only('plan__discount_percent', 'service_id')
subscriptions = []
for i_subscription in queryset:
new_price = service_instance.price - service_instance.price * i_subscription.plan.discount_percent / 100
i_subscription.price = new_price
subscriptions.append(i_subscription)
Subscription.objects.bulk_update(subscriptions, fields=['price'])
@shared_task()
def set_comment(service_instance_id):
from .models import Subscription, Service
service_instance = Service.objects.get(id=service_instance_id)
queryset = service_instance.subscriptions.all()
subscriptions = []
for i_subscription in queryset:
i_subscription.comment = str(datetime.datetime.now())
subscriptions.append(i_subscription)
time.sleep(20)
Subscription.objects.bulk_update(subscriptions, fields=['comment'])