Задать вопрос
  • Демон в celery для django: какнастроить?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Прежде всего хочу обратить внимание вот на это:
    Выбрал вариант с celeryd

    Если вы "выбирали" между celeryd или celerybeat, то тут выбор бессмысленен: celeryd - демон для выполнения заданий, celerybeat - следит за расписанием заданий, отправляя их в заданное время на выполнение. Так что, если у вас есть надобность выполнять задания по расписанию, настраивать надо оба демона.

    Теперь немного ответов на вопросы.

    CELERY_APP - что сюда вписывать?

    Это экземпляр класса celery.Celery, вот путь до него и надо прописать, в формате package[.subpackages].module:variable. Например, у меня есть файл project/celery.py, в котором создаётся экземпляр таким образом:
    from celery import Celery
    
    app = Celery('project')

    И я впишу в CELERY_APP значение project.celery:app
    У вас наверняка подобный код тоже есть в проекте, если вы делали по документации

    И как создать celery-пользователя? Погуглил, но не понял ответа.

    Я для всего проекта использую одного пользователя, того, под которым django выполняется (у меня webapp)

    И почему CELERYD_CHDIR="/opt/Myproject/"? Так и не понял, зачем нужен редирект куда-то (а я так понял, это адрес, куда переместиться во время работы). Зачем это нужно и помешает ли сохранять получаемые данные (сохранять изображения в папках) по относительным адресам в django-проекте?

    Эту опцию не использую, вместо неё у меня используется WorkingDirectory на уровне systemd, но смысл абсолютно тот же.
    Это не редирект, это просто указание рабочей папки, относительно которой будет запускаться ваш демон. При правильной настройке работа проекта в режиме celery-воркера ничем не должна отличаться от работы проекта в веб-режиме. На уровне кода никаких ветвлений на тему "если я демон - то делай так, а если нет - делай эдак" быть не должно (и я даже не знаю, как их вообще делать).

    CELERY_BIN="/usr/local/bin/celery"
    Прошел по пути, никакого celery там не увидел.

    Ну блин, куда вы установите celery, там его исполняемый файл и будет. Например, у меня все python-зависимости, куда входит и celery, установлены в virtual env'е, и путь до него такой: /home/webapp/Env/project-backend-3.5/bin/celery

    2. Что делать после настройки? В документации указано что-то про django-настройки и пояснено значение переменных, прилагается несколько кусков кода, но даже с переводчиком не могу понять их назначения.

    Что делать после того, как я сделаю оба файла celeryd пригодными для работы?

    После настройки - запускать, тестировать, отлаживать. Всё как обычно.

    CELERYD_SU_ARGS="-l"
    Что это? Зачем это?

    Не знаю, и видимо, не нужно. Там даже написано, что не рекомендуется.

    Вот мои конфиги (для systemd), делал на основе конфигов из официальной репы celery.

    Файл сервиса celeryd (/etc/systemd/system/celery.service):
    [Unit]
    Description=Celery Service
    After=network.target redis.target
    
    [Service]
    Type=forking
    User=webapp
    Group=webapp
    EnvironmentFile=-/etc/systemd/celery.conf
    WorkingDirectory=/home/webapp/project_dir/project/src
    PermissionsStartOnly=true
    ExecStartPre=-/bin/mkdir -p ${CELERYD_STATE_DIR}
    ExecStartPre=/bin/chown -R ${CELERYD_USER}:${CELERYD_GROUP} ${CELERYD_STATE_DIR}
    ExecStart=/bin/sh -c '${CELERY_BIN} multi start \
        ${CELERYD_NODES} \
        -A ${CELERY_APP} \
        --pidfile=${CELERYD_PID_FILE} \
        --logfile=${CELERYD_LOG_FILE} \
        --loglevel=${CELERYD_LOG_LEVEL} \
        ${CELERYD_OPTS}'
    ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait \
        ${CELERYD_NODES} \
        --pidfile=${CELERYD_PID_FILE}'
    ExecReload=/bin/sh -c '${CELERY_BIN} multi restart \
        ${CELERYD_NODES} \
        -A ${CELERY_APP} \
        --pidfile=${CELERYD_PID_FILE} \
        --logfile=${CELERYD_LOG_FILE} \
        --loglevel=${CELERYD_LOG_LEVEL} \
        ${CELERYD_OPTS}'
    
    [Install]
    WantedBy=multi-user.target


    Файл сервиса celerybeat (/etc/systemd/system/celerybeat.service):
    [Unit]
    Description=CeleryBeat Service
    After=network.target redis.target rabbitmq.target
    
    [Service]
    Type=simple
    User=webapp
    Group=webapp
    EnvironmentFile=-/etc/systemd/celery.conf
    WorkingDirectory=/home/webapp/project_dir/project/src
    PermissionsStartOnly=true
    ExecStartPre=-/bin/mkdir -p ${CELERYBEAT_STATE_DIR}
    ExecStartPre=/bin/chown -R ${CELERYD_USER}:${CELERYD_GROUP} ${CELERYBEAT_STATE_DIR}
    ExecStartPre=/bin/rm ${CELERYBEAT_SCHEDULE}
    ExecStart=/bin/bash -c '${CELERY_BIN} beat \
        -A ${CELERY_APP} \
        --workdir=${CELERYBEAT_WORKDIR} \
        --pidfile=${CELERYBEAT_PID_FILE} \
        --logfile=${CELERYBEAT_LOG_FILE} \
        --loglevel=${CELERYBEAT_LOG_LEVEL} \
        --schedule=${CELERYBEAT_SCHEDULE}'
    ExecStop=/bin/systemctl kill celerybeat.service
    
    [Install]
    WantedBy=multi-user.target


    Файл конфигурации сервисов celeryd и celerybeat (/etc/systemd/celery.conf):
    # See
    # http://docs.celeryproject.org/en/latest/tutorials/daemonizing.html#available-options
    
    # Common Celery Settings
    CELERY_BIN="/home/webapp/Env/project-backend-3.5/bin/celery"
    CELERYD_USER="webapp"
    CELERYD_GROUP="webapp"
    CELERY_APP="project.celery:app"
    
    # Common env settings
    DJANGO_SETTINGS_MODULE=settings.production
    LC_ALL=ru_RU.UTF-8
    LC_LANG="ru_RU.UTF-8"
    LANG=ru_RU.UTF-8
    
    # Worker settings
    CELERYD_NODES="w1 w2 w3 w4 w5 w6"
    CELERYD_OPTS="-Q:w1 default --autoscale:w1=8,4 \
    -Q:w2 queue2 --autoscale:w2=6,2   \
    -Q:w3 queue3 --autoscale:w3=8,2 \
    ....................
    -Q:w6 queue6 --autoscale:w6=6,2       "
    
    CELERYD_MULTI="multi"
    CELERYD_STATE_DIR="/var/run/celery"
    CELERYD_PID_FILE="/var/run/celery/%n.pid"
    CELERYD_LOG_FILE="/var/log/celery/%n.log"
    CELERYD_LOG_LEVEL="INFO"
    
    # Beat settings
    CELERYBEAT_STATE_DIR="/var/run/celerybeat"
    CELERYBEAT_PID_FILE="/var/run/celerybeat/beat.pid"
    CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"
    CELERYBEAT_LOG_LEVEL="INFO"
    CELERYBEAT_SCHEDULE="/var/run/celerybeat/schedule"
    CELERYBEAT_WORKDIR="/home/webapp/project_dir/project/src"
    Ответ написан
    5 комментариев
  • Как отправить письмо через 5 минут после return?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    В голой Джанге отложенная отправка письма в рамках обработки http-запроса видится мне очень костыльной, в любом случае, делегировать отправку письма каким-нибудь способом нужно внешнему сервису.

    Если письмо отправляется с помощью какого-нибудь сервиса (а не просто SMTP) - наверняка в его API есть возможность отложенной отправки.
    Если используется Celery - опция countdown в помощь.

    UPD:
    Руслан Ежгуров: Если ничего из вышеперечисленного не используется. Celery обычно сложнее интегрировать с проектом, поэтому начните отправлять почту через какой-либо сервис. Из последнего годного, с чем сам работал - SparkPost, для небольших и средних проектов бесплатных лимитов хватает за глаза. Заодно решите проблемы с доставкой/недоверием к вам почтовых сервисов (ну, это сами спамить не будете, а то вас сам спаркпост отрубит быстро).
    Библиотека для интеграции с Python/Django python-sparkpost, в методе отправки сообщения есть возможность отложенной отправки (см. параметр start_time)
    Ответ написан
    2 комментария
  • Не могу сделать связку комментариев в Django?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Если говорить о вьюхе вывода, то сначала надо получать саму "блогозапись", а потом уже по ней фильтровать комментарии, т.е. просто поменять местами 2 строки и дописать фильтр:
    def full_slug(reguest, slug):
        comment_form = CommentForm
        form = comment_form
        te = get_object_or_404(BlogPost, slug=slug)
        comments = Comments.objects.filter(comments_blogpost=te)
        return render(reguest, 'full.html', {'te': te, 'form': form, 'comments': comments, 'username': auth.get_user(reguest).username})
    Ответ написан
  • Как передать в Unit1 объект, который находится в Unit3, избегая ошибки: Circular unit reference to ‘Unit3′?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Плохо помню Delphi, попробуйте перенести в одном из модулей конфликтный uses из interface в implementation. Как раз вот кстати в этом модуле, куски кода которого у вас приведены.
    Ответ написан
  • Как принудительно заставить программу держать обмен мобильными данными(интернет)?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Держать интернет всегда включенным пытаться не стоит. Соединение может разорваться по многим причинам, на которые повлиять вы не в силах. Лучше повлияйте на способ авторизации, чтобы она не терялась. Ведь вы же на компьютере в браузере авторизуетесь на каких-то сайтах, какие-то приложения держите на телефоне, которые авторизацию со своим сервером требуют - проблемы у них такой нет.
    Ответ написан
  • Где и как правильно хранить javascript и jquery?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Недавно был вопрос: Как правильно хранить javascript?
    В общем, всё правильно, но скрипты типа jquery лучше тянуть из общедоступных CDN (большая вероятность что он уже закэширован у клиента), ну и сжимать и конкатенировать скрипты (и стили) для отдачи клиенту.
    Ответ написан
    Комментировать
  • Как правильно хранить javascript?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Отказываться не нужно, в наше-то время. Несколько общих рекомендаций:
    • В head'е могут быть только самые необходимые скрипты, которым это нужно. Например, аналитика, счётчики, возможно что и jquery (просто по привычке его всегда в head'е прописываю)
    • Остальные скрипты нужно убирать в самый конец страницы.
    • Скрипты, как и стили, кстати, для ускорения загрузки надо сжимать и сливать в один файл
    Ответ написан
    Комментировать
  • Как включить перенос строк в eclipse?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Когда я пользовался версией Indigo, надо было для этого ставить плагин:
    stackoverflow.com/questions/2846002/does-eclipse-h...
    Ответ написан
  • Может ли Celery писать результат в бд на другом хосте?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Сам недавно разворачивал Celery. Пока тоже всё крутится на одном сервере.
    1. Ваша БД, с которой работает django-проект, и celery result backend - вещи разные. Последнее - это, грубо говоря, хранилище для значений, которые вы можете вернуть из отложенного задания. А БД проекта - это БД проекта, хотя и может так же выполнять функцию result backend'а. Кстати, вы можете вообще не использовать result backend, если не вам не требуется что-то возвращать из заданий.
    2. Рабочие процессы вашего django-проекта и celery-воркеры - одно и то же, только запущенное через разные точки входа. Для веба - это, скорее всего, wsgi.py, для celery, к примеру, celery.py.
    3. Чтобы запустить воркеры на 2м сервере (вместо 1го или в дополнение к нему), вам нужно будет развернуть ваш проект на нем, и сделать всё то же самое, что и на 1м сервере, чтобы заработали celery-воркеры.
    4. помимо подключения в БД, вам также нужно будет озаботиться подключением к брокеру и result backend'у (если используете его). В самом простом случае, как мне видится, никаких IP не надо будет менять - зачем, если сервер БД у вас один, и находится на 1м сервере. Ну разве что вместо 127.0.0.1 нужно будет прописать нормальный адрес.
    Ответ написан
    Комментировать
  • Проблема c @font-face на mac os и linux, как решить?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Даже если у вас нет грубых ошибок в подключении, то могут быть несовместимые с ОС форматы шрифта. Вот так должно работать везде, но вам придётся заиметь ваш шрифт в нескольких различных форматах (сервисы конвертации вам в помощь).
    @font-face {
      font-family: 'rouble_regular';
      src: url('../font/rouble-regular.eot');
      src: local('☺'), url('../font/rouble-regular.eot?') format('embedded-opentype'), url('../font/rouble-regular.woff') format('woff'), url('../font/rouble-regular.ttf') format('truetype');
    }

    Про local('☺') не спрашивайте, это какой-то хак для IE. На знак вопроса в url() тоже обратите внимание и не потеряйте.
    Кстати, вот ещё статья про это дело: habrahabr.ru/post/113136
    Ответ написан
    1 комментарий
  • Как автоматически устанавливать значение поля Inline модели в админке?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    А разве это сама Django автоматом не делает? Это поле - связь между двумя моделями, и никаких телодвижений не должно требовать.
    Если имеете, к примеру, страницу добавления сущности Автор в админке, и на ней же инлайны с сущностями Книга - то при добавлении автора и нескольких его книг, в БД создастся 1 запись в таблице авторов, и необходимое количество записей в таблице книг, связанных с этим добавленным автором.
    Ответ написан
    Комментировать
  • Как ускорить скрипт Python?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Вы, может быть, хотели бы использовать цикл в таком виде (python3):
    for x in range(1, 100):  # в Py2 вроде xrange используется
        url=urllib.urlopen('www.ya.ru')
        print(url.read().splitlines())


    По сути вопроса: у вас в цикле происходит http-запрос, как вы его хотите ускорить?
    Эта часть вашего кода оптимизируется путем ускорения интернета + можно, если дёргаете в цикле свой сайт, оптимизировать страницу, к которой 100 раз обращаетесь.
    Ответ написан
    Комментировать
  • Как сконвертировать офисные документы (doc/docx/xls/xlsx) в pdf на python под убунтой?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Можно посмотреть в сторону скрипта на питоне, работающего с запущенным инстансом Libre/Open Office'а: blog.swlogic.eu/2011/06/03/rabota-s-openoffice-lib...
    UPD. Эхехе, метод подразумевает использование того же uno, что используется в unoconv, если я правильно понял
    Ответ написан
  • FB API. Проверить сделал ли пользователь репост?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    У FB тоже есть обработка событий: https://developers.facebook.com/docs/reference/jav...
    А конкретно по репосту - вот пара ссылок, 13й год, но работать должно
    stackoverflow.com/questions/20152828/is-there-a-fa...
    stackoverflow.com/questions/20312964/callback-func...
    Ответ написан
    1 комментарий
  • Возможно ли формировать динамически условия во время выполнения?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Не знаю, что у вас за ORM (если это вообще он), в обычном Django ORM, когда мне надо было динамически сформировать запрос, я делал примерно так:
    # кортеж с фильтрами
    filters = (Q(field1='value1'), )
    for value in values:  # перебираем итератор со значениями для фильтрации
        # добавляем в кортеж очередное условие через ИЛИ
        filters |= Q(field1=value)
    queryset = MyModel.objects.filter(filters)

    Пример немного высосан из пальца (можно было просто написать field1__in=values, грубо говоря), но показывает, как можно формировать динамически условия, комбинировать их как надо, и т.п.
    Ответ написан
    4 комментария
  • Целесообразно ли хранить картинки в БД?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Оба методы имеют свои достоинства и недостатки, но всё же хранение в виде простых файлов более органично. Это статика, которую нужно отдавать пользователю без участия скриптов.
    Ответ написан
    Комментировать
  • Серверный таймер на jQuery?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Какая точность нужна?
    Вообще, вижу 3 способа:
    - от стартующего уходит запрос на сервер, в БД или куда-нибудь ещё ставится флаг "отсчёт начат". Те самые 10к клиентов периодически, раз в секунду к примеру, делают ajax-запрос на сервер и узнают, начался отсчёт или нет. Точность зависит от периодичности запросов + сетевые лаги. Особых требований к софту в этом случае нету, но должен быть хорошо настроен сам вебсервер, чтобы выдерживать такой поток запросов, пусть и очень лёгких.
    - вебсокеты. Все ваши 10к клиентов имеют постоянное соединение с сервером, один из них по сокету посылает серверу сигнал "отсчёт начат", сервер сразу же рассылает его всем остальным. Тут уже надо настраивать демона, к которому собственно 10к клиентов и будут присоединены и который будет принимать и рассылать им сообщения. Точность зависит чисто от сети.
    - есть еще dklab_realplexor от Котерова. Используются long polling-запросы, эдакие "вебсокеты для бедных", но вообще работает решение это неплохо. Сам использовал на продакшне, но на очень маленьких нагрузках, а вот tjournal.ru его использует для организации онлайн-трансляций, и там нагрузки значительно больше.
    Ответ написан
  • Как в Django через ORM сделать SQL-запрос с INNER JOIN?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Вам поможет annotate

    Подробнее вот тут: https://docs.djangoproject.com/en/dev/topics/db/ag...
    Вот вроде неплохой пример с annotate и сортировкой по count(): stackoverflow.com/questions/1396264/how-to-sort-by...
    Ответ написан
  • Чем опасен высокий ток от батареи в 3,7 - 5V DC конверторе?

    Assargin
    @Assargin
    Перед ответом смотрю наличие ✔ в ваших вопросах
    Насколько я знаю, потолок тока всего лишь означает, сколько его максимум можно взять, но это ни разу не значит, что именно именно 20А и будет. Чисто житейски: подключая к элементу 18650 заряжаться телефон, я этот элемент разряжу за несколько часов, если же подключить светодиод, то от такой батарейки много дней он может гореть - светодиод потребляет меньше.
    Ответ написан
    Комментировать