По поводу вашего вопроса. Как сделать так чтобы none не создавалось. Я в docker-compose после build вниз добавил image питона такой же как в Dockerfile. Вроде после этого перестает создаваться
Можно в методе save() указать параметр update_fields в ф-ции set_price равный ('price', ) , в ф-ции set_comment равный ('comment', ). Тогда update в sql запросе не будет перезатирать все значения (можно чекнуть логи) объекта, а только указанные в update_fields. В данном случае эти 2 таски можно запустить параллельно.
Я просто взял этот кейс чтобы продемонстрировать проблему. В любом случае синглтон нужен , мы не можем всегда и везде это предусмотреть, особенно в немаленьких проектах
Спасибо большое, Узнал много нового, долго игрался с тасками, не обновлялся прайс, но почему-то когда создал новую подписку в ней все работало. Удалил старые и в новых все хорошо работает, очень интерсесно.
Спасибо за видосы, одна маленькая просьбочка! Перед выгрузкой видео ускоряй его слегка, потому что лично мне ютубовского 2х мало для просмотра твоего контента))
Можно зайти в контейнер и там уже писать команды,так image не будут создаваться ,а результат будет тот же, хотел тебе ещё задать вопрос - а почему не пользуешься тайпхинтами?
Да, согласен, через docker exec вроде так же работает. Тайпхинты - мы много спорили с коллегами по этому вопросу. Мое мнения что питон хорош тем, что это минималистичный, легко-читаемый язык. Если его превращать в Java по синтаксису, он никак не получит сильные стороны от Java, скорее получит его недостатки. в 99% случаев тайпхинты не нужны, когда и так очевидно что это за тип по названию. Но это зависит от проекта, конечно. Где-то они будут в тему. А вообще это спорный вопрос, кто-то прям за них всегда топит.
а чем больше воркеров тем выше нагрузка на систему правильно? а если сам проект тяжелый? это же сильно по ресурсам бьет, есть ли альтернативные варианты выполнения тасков на такой случай?
Ну чем больше воркеров, тем больше запросов в базу, тем больше нагрузка на базу. Никак по-другому они систему не нагружают. Чтобы решить проблему нагрузки на базу лучше саму базу оптимизировать, добавить кеш, сделать еще read only базы и тд. Уменьшая количество Волкеров мы просто уменьшим производительность системы вцелом
Доброго времени суток! Благодарю за прекрасные курсы! Возник вопрос - если в Celery длительность очереди может быть большая, к примеру, час, то с этим возникают некоторые проблемы: - Если сервер перезагрузится по какой либо причине, таски исчезнуть, а значит и вся информация, которая должна была обновится, не будет обновляться. - Если я выключу сервер для обновления версии софта, то будет та же проблема - все таски слетят. Я чего-то не так понял и этих проблем не существует или для них уже есть решения?
Да, я думаю что проблемы будут скорее с тасками, которые уже запущены и в процессе выполнения на момент перезагрузки . Вроде была какая-то опция чтобы celery их перезапускал после перезагрузки, надо посмотреть в доке
Я не до конца понял необходимости добавления в запрос select_for_update? Зачем? Судя по доке, лочит строки в таблице, но мы вроде также используем менеджер transaction.atomic, который гарантирует, что операция будет выполнена полностью или не выполнена вовсе.... Можно пояснить подробнее про эту связку?
Это разные вещи. Atomic делает операцию атомарной, а select for update чтобы параллельные таски не пытались изменить объект , по тому что их изменения могут быть перезаписаны . На видео я опытным путем подтверждаю эту необходимость , если досмотреть до конца .
Привет. Ну в видео я показал два варианта: без трансакции и с ней. И то, как трансакция решает показанную проблему. Уровни изоляции они присутствуют в трансакциях. Без них не существуют. Тут же проблема что мы создали объект кода python , и он устарел , пока мы что-то делали , а потом мы его сохранили и он перезатер. Вообщем это немного другая ситуация.
А зачем мы используем transaction.atomic? Ведь select_for_update уже блокирует объекты модели для использования другим воркером. Если сделать то же самое без transaction.atomic, что изменится?
Почему когда вы добавили транзакции и воркеры разобрали таски, один таск закончился намного раньше и не ждал 20+27 секунд? Куда делись эти самые sleep?
попробуй запускать команды в нужном контейнере через следующую команду: "docker-compose exec containe_name some_command_in_container" и в этом случае не будет создаваться новый контейнер
Еще раз спасибо! Офигенный разбор! 👍👍👍 Правда, у меня косяк не воспроизводится, 😄 видимо, потому что я пошел путем апдейтов, а не сейвов: 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
Ох уж эти параллельные таски, с ними надо максимально аккуратно работать.
Спасибо за еще одно чудесное видео!
Курс просто бомба !❤🔥
Удалить неиспользуемые образы: docker rmi $(docker images -q -f dangling=true)
Удалить контейнеры: docker rm $(docker ps -a -q -f status=exited)
Чтобы избежать копипаста в docker-compose можно использовать якоря (&) и ссылки (
а можно пример?
По поводу вашего вопроса. Как сделать так чтобы none не создавалось. Я в docker-compose после build вниз добавил image питона такой же как в Dockerfile. Вроде после этого перестает создаваться
Можно в методе save() указать параметр update_fields в ф-ции set_price равный ('price', ) , в ф-ции set_comment равный ('comment', ). Тогда update в sql запросе не будет перезатирать все значения (можно чекнуть логи) объекта, а только указанные в update_fields. В данном случае эти 2 таски можно запустить параллельно.
Я просто взял этот кейс чтобы продемонстрировать проблему. В любом случае синглтон нужен , мы не можем всегда и везде это предусмотреть, особенно в немаленьких проектах
Вероятно образы с именем 'None' создаются, когда мы делаем ребилд. Имя затирается, а старый образ становится None
Спасибо большое, Узнал много нового, долго игрался с тасками, не обновлялся прайс, но почему-то когда создал новую подписку в ней все работало. Удалил старые и в новых все хорошо работает, очень интерсесно.
Большое спасибо, крутые видосы
Благодарю
как вариант, в таких не больших тасках, можно было бы просто использовать .save(update_fields=['comment'])
да, но поднятая проблема тоже актуальна, хотя ваше решение- снимает часть головной боли
Уже жду следующий выпуск , как в сериале залип
В asyncio таски ведь не уходят ни в другой поток, ни в другой процесс, они в едином цикле событий, который в одном потоке 00:53
Спасибо за видосы, одна маленькая просьбочка! Перед выгрузкой видео ускоряй его слегка, потому что лично мне ютубовского 2х мало для просмотра твоего контента))
Это чтобы оставалось время подумать! )
Лучший канал по Django! Будут ли видосы про автоматизацию деплоя Django проекта через github actions + zero downtime deployment?
Может будут , да тема вцелом не сложная ..
спасибо!😎
спасибо!
Так много вкусного!
😁
👍
Можно зайти в контейнер и там уже писать команды,так image не будут создаваться ,а результат будет тот же, хотел тебе ещё задать вопрос - а почему не пользуешься тайпхинтами?
Да, согласен, через docker exec вроде так же работает.
Тайпхинты - мы много спорили с коллегами по этому вопросу. Мое мнения что питон хорош тем, что это минималистичный, легко-читаемый язык. Если его превращать в Java по синтаксису, он никак не получит сильные стороны от Java, скорее получит его недостатки. в 99% случаев тайпхинты не нужны, когда и так очевидно что это за тип по названию.
Но это зависит от проекта, конечно. Где-то они будут в тему. А вообще это спорный вопрос, кто-то прям за них всегда топит.
а чем больше воркеров тем выше нагрузка на систему правильно? а если сам проект тяжелый? это же сильно по ресурсам бьет, есть ли альтернативные варианты выполнения тасков на такой случай?
Ну чем больше воркеров, тем больше запросов в базу, тем больше нагрузка на базу. Никак по-другому они систему не нагружают. Чтобы решить проблему нагрузки на базу лучше саму базу оптимизировать, добавить кеш, сделать еще read only базы и тд. Уменьшая количество Волкеров мы просто уменьшим производительность системы вцелом
Доброго времени суток! Благодарю за прекрасные курсы!
Возник вопрос - если в Celery длительность очереди может быть большая, к примеру, час, то с этим возникают некоторые проблемы:
- Если сервер перезагрузится по какой либо причине, таски исчезнуть, а значит и вся информация, которая должна была обновится, не будет обновляться.
- Если я выключу сервер для обновления версии софта, то будет та же проблема - все таски слетят.
Я чего-то не так понял и этих проблем не существует или для них уже есть решения?
если я правильно понимаю, таски хранятся в Redis(БД) и селереи после перезапуска чекает редис.
Да, я думаю что проблемы будут скорее с тасками, которые уже запущены и в процессе выполнения на момент перезагрузки . Вроде была какая-то опция чтобы celery их перезапускал после перезагрузки, надо посмотреть в доке
@@BorisenkoV89Разве редис не очищается после перезагрузки системы?
Я не до конца понял необходимости добавления в запрос select_for_update? Зачем? Судя по доке, лочит строки в таблице, но мы вроде также используем менеджер transaction.atomic, который гарантирует, что операция будет выполнена полностью или не выполнена вовсе.... Можно пояснить подробнее про эту связку?
Это разные вещи. Atomic делает операцию атомарной, а select for update чтобы параллельные таски не пытались изменить объект , по тому что их изменения могут быть перезаписаны .
На видео я опытным путем подтверждаю эту необходимость , если досмотреть до конца .
Привет. Можно ли решить проблему параллелизма изменив уровень изоляции транзакций в самой бд? Например поставить repeatable read?
Привет. Ну в видео я показал два варианта: без трансакции и с ней. И то, как трансакция решает показанную проблему.
Уровни изоляции они присутствуют в трансакциях. Без них не существуют.
Тут же проблема что мы создали объект кода python , и он устарел , пока мы что-то делали , а потом мы его сохранили и он перезатер. Вообщем это немного другая ситуация.
А зачем мы используем transaction.atomic? Ведь select_for_update уже блокирует объекты модели для использования другим воркером. Если сделать то же самое без transaction.atomic, что изменится?
Select for update не работает вне transaction
@@SeniorPomidorDeveloper спасибо большое что отвечаете всем нам
Уроки по FastApi есть в планах ?
Пока нет. Может в следующем курсе
Столкнулся с проблемой, что из двух задач всегда выполнялась только одна. Никак кроме удаления Singleton решить не смог
А разве singletone не для этого?
Почему когда вы добавили транзакции и воркеры разобрали таски, один таск закончился намного раньше и не ждал 20+27 секунд? Куда делись эти самые sleep?
А в каком моменте видео это было?
@@SeniorPomidorDeveloperна 25:05. И потом ещё вы говорите: "видно, что одна таска отработала значительно быстрее"
Скорее всего на монтаже видео так неудачно подрезал. Там вроде дольше должен быть sleep , да
@@SeniorPomidorDeveloper понятно. Спасибо большое. Отлично объясняете.
@user-kn5ip9lr6r спасибо что смотрите!
попробуй запускать команды в нужном контейнере через следующую команду: "docker-compose exec containe_name some_command_in_container" и в этом случае не будет создаваться новый контейнер
а где можно исходные коды посмотреть?
Тут github.com/chepe4pi/service_app
Еще раз спасибо! Офигенный разбор! 👍👍👍
Правда, у меня косяк не воспроизводится, 😄 видимо, потому что я пошел путем апдейтов, а не сейвов:
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'])