Задать вопрос
  • Почему Dockerfile не видит entrypoint.sh - no such file or dir при поднятии compose-ом?

    @alexandrsharganov
    У меня была похожая проблема. Суть была в том, что git при сохранении изменений и отправке их на GitHub некоторые файлы типа LF переделывал в CRLF. И я не понимал, почему проект в папке - в которой я его разворачивал и в которой работал с самого начала - нормально поднимается в Docker, а скаченный с репозитория(на другой комп например или на тот же но в другую папку) - нет.
    Возможно поможет вот это - Что такое LF, CLRF и как с этим бороться?
    Я же решил проблему добавив в корень проекта файл .gitattributes с таким содержимым:

    docker-compose.yml text eol=lf
    Dockerfile eol=lf
    *.sh text eol=lf


    А уже измененные файлы вернул из состояния CRLF в LF при помощи VS Code(в котором и работал)
    64d64db1a7637611269641.png
    Ответ написан
    1 комментарий
  • Зачем вообще использовать брокеры очередей?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    В первую очередь брокеры нужны для балансировки нагрузки и увеличения надежности и скорости работы системы в целом.

    В вашем приведенном примере приведен способ уведомления клиента о каком-то событии. Например о том, что его заказ обработан, отправлен, доставлен и т.д. Событий может быть много и их источники могут быть различными.
    Например у вас может быть интеграция со сторонней системой логистики. А еще с 10 разными системами оплаты.
    Еще есть маркетинг, который тоже хочет отправлять массовые рассылки.
    Получается, что под каждый случай вам прийдется хранить информацию о письмах и статусах. Но даже проблема не в этом, проблема в том, что каждое событие имеет разный приоритет и разную ценность.

    В случае работы с сайтом у вас будет 1 воркер, который будет просто сканировать таблицы на поиск неуведомленных пользователей. Если у вас будет 2 воркера, надо делать систему блокировок и т.д. Т.е. мы упираемся в проблему масштабирования. Для решения задачи разной скорости уведомлений, вы построите систему приоритетов или будете делать разные таблицы с разными воркерами. Это все будет работать, но нагрузка на базу будет серьезной и она будет увеличиваться с ростом пользовательской базы. Опять вы упретесь в тормоза.
    Опять же есть письма, которые должны быть доставлены немедленно, вроде подтверждений аккаунта, смены пароля и т.д. Еще одна таблица? Дополнительный приоритет? Может так произойти, что вы некоторые пользователи вообще никогда не получат писем и уведомлений. Прийдется придумывать способ контроля.
    Я уж не говорю о куче кастомных воркеров под каждую ситуацию. И их будет с десяток, не меньше.

    Очереди решают, т.к. можно сделать их несколько и на для каждой настроить определенное количество абсолютно одинаковых воркеров. Пример с поллингом отвратителен и сейчас никто так не делает, а с очередями делают так.
    У вас может быть цепочка из нескольких воркеров, когда результат работы одного помещается в очередь.
    Например, когда надо сначала достать данные из нескольких разных медленных систем, отрендерить в шаблон, а потом отправить письмо. Сборка, рендеринг и отправка - три разные компонента, последние два из которых, можно активно переиспользовать для других целей изменяя лишь конфигурацию времени исполнения.
    При таком подходе проще развивать кодовую базу, исправлять ошибки, т.к. они изолированы в одном месте, а не разбросаны по всей системе. И да, косяк в "горячем" модуле вы заметите немедленно. А самое прикольное то, что ваш косяк, пользователи и не заметят, для них это будет выглядеть как простая задержка, а у вас будет время на то, чтобы исправить ошибку. Сообщения посидят в очереди и все.
    Но это еще не все, ваши воркеры могут быть написаны на разных языках программирования. Например пользователь может загружать фото на сайт на PHP, объекты распознаваться на Python, видео рендериться на Rust, а отправка писем может быть на Go. И такой подход может подойти для сложных систем с распределенными командами и различным уровнем компетенция в применяемых технологиях. Специалистов превосходно владеющих всеми приведенными технологиями просто единицы, и поверьте, они решают задачи совершенно другого уровня.
    Ответ написан
    Комментировать
  • Зачем вообще использовать брокеры очередей?

    Очередь это буфер, куда задачи попадают с разной скоростью, а из него сливаются равномерно, по мере готовности «рабочих» их принять.

    В вопросе описана так-себе реализация с поллингом очереди. Различие без-очереди и с-очередью — в направлении инициативы:
    • без очередей «рабочий» опрашивает базу снова и снова: «есть чё?». Это как из браузера ajax'ом пинговать сервер раз в секунду в поиске сообщений. Работает, но такое себе..
    • с очередью инициатор процесса – брокер. Это брокер передаёт очередную задачу на исполнение первому освободившемуся «рабочему».

    spoiler
    Про потерю данных при падении — че-т страшилка, далёкая от продакшена. Драйвером очереди может быть и Redis (со своей персистентностью) и MySQL какой-нибудь, и другие. Имхо костыльно пихать в очередь всего лишь id записи в БД, которую надо обработать – чтобы рабочий, взявший задачу, заново собирал данные. Это не кошерно и калорийно.

    Лучше класть в очередь самодостаточную задачу. Например, сериализовать модель. Чтобы рабочий, получивший задачу, уже не обращался к базе – а только наполнял темплейт письма данными из полученной модели и отправлял послание. И в БД проставлял статус «отправлено»
    Ответ написан
    Комментировать
  • Ошибка в тесте AttributeError: `bytes` has no attribute `status_code`?

    @inception007
    Возможно новичкам поможет.
    Метод имеет следующую сигнатуру согласно документации:
    SimpleTestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)

    Поэтому нужно передать response, а не response.content
    Ответ написан
    Комментировать
  • Как в django вывести в шаблон count всех объектов подподкатегории?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    Прежде всего, если используете иерархические структуры данных, то используйте их с django-mptt. Во-первых, это позволит работать с любым уровнем вложенности, в том числе неопределённым на этапе разработки и переменным в разных ветках. Во-вторых, это облегчит вам работу, предоставив простые и эффективные методы манипуляции ветками. Наконец, это позволит получать данные из БД наиболее быстрым и эффективным способом, с минимальной затратой ресурсов.

    Конкретно по вашей задаче решением в лоб было бы определить в модели свойство, возвращающее количество объявлений в дочерних категориях:
    class Category(models.Model):
        parent = TreeForeignKey('self', verbose_name=u'Родитель', null=True, blank=True, related_name='children')
        title = models.CharField(u'Название', max_length=100)
    
        @property
        def items_count(self):
            # получаем список идентификторов всех низлежащих категорий, включая интересующую нас
            ids = self.get_descendants(include_self=True).values_list('id')
            # возвращаем количество товаров, имеющих родителем категорию с идентификатором входящим
            # в список полученный строкой выше
            return Product.objects.filter(parent_id__in=ids).count()

    и потом вывести их в шаблоне как-то так
    <ul class="root">
        {% recursetree nodes %}
            <li>
                {{ node.title }}<span>{{ note.items_count }}</span>
                {% if not node.is_leaf_node %}
                    <ul class="children">
                        {{ children }}
                    </ul>
                {% endif %}
            </li>
        {% endrecursetree %}
    </ul>

    Но беда в том, что это квадратичный алгоритм, чем больше будет категорий отображаться на странице, тем больше запросов будет к базе при открытии этой страницы. Я так и не нашёл в Django лучшего решения для этого, чем делать сырой SQL запрос к базе:
    SELECT name, cp.p_count FROM catalog_category AS cc
    INNER JOIN LATERAL (
      SELECT cc.id AS id, SUM(products) AS p_count FROM (
        SELECT cc.id AS parent_id, category_id, COUNT(id) AS products
        FROM catalog_product
        WHERE category_id IN (
          SELECT id FROM catalog_category
          WHERE lft <= cc.rght AND lft >= cc.lft AND tree_id = cc.tree_id)
          GROUP BY category_id
        ) AS sub_cс
      GROUP BY parent_id
    ) AS cp
    USING(id) ORDER BY name;
    Ответ написан
    5 комментариев
  • Как отменить форк репозитория (unfork) на GitHub?

    yarkov
    @yarkov
    Помог ответ? Отметь решением.
    В настройках репозитория удалить его нужно
    Ответ написан
    Комментировать
  • Как запустить Selenium (Python) на VPS?

    qlkvg
    @qlkvg
    python backend developer
    https://tecadmin.net/setup-selenium-chromedriver-o...
    Если не нужен селениум-сервер, то сделать первые 3 шага и разобраться, как из скрипта запускать хром в безголовом режиме. Главное заранее приготовиться к боли и страданиям в процессе.
    Ответ написан
    Комментировать
  • Как сгруппировать строки c картинками в excel средствами PHP?

    @ligaliga
    SilverSlice Спасибо за наводку! Не много скорректировал PHPExcel и все получилось, но при условии что картинка в пределах одной ячейки (мне нужно было для прайс-листа). Если картинка вылазит за пределы этой ячейки нужно будет еще думать.

    В PHPExcel есть метод setResizeProportional, но он вообще ни где не задействован в PHPExcel/Writer/Excel2007/Drawing.php @version 1.7.9.

    Добавил корректировки в функцию public function _writeDrawing у меня это 172 строчка:

    Было :
    $objWriter->startElement('xdr:oneCellAnchor');

    Стало:

    $aResizeProportional = $pDrawing->getResizeProportional();
    
    			if ($aResizeProportional) {
    				$objWriter->startElement('xdr:twoCellAnchor');
    			}
    			else {
    				$objWriter->startElement('xdr:oneCellAnchor');
    			}


    И еще одна правка чуть ниже

    Было :
    // xdr:ext
    					$objWriter->startElement('xdr:ext');
    						$objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));
    						$objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));
    					$objWriter->endElement();


    Стало

    if ($aResizeProportional) {
    					$objWriter->startElement('xdr:to');
    						$objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
    						$objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX()) + PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));
    						$objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
    						$objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY()) + PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));
    					$objWriter->endElement();
    				} else {
    					// xdr:ext
    					$objWriter->startElement('xdr:ext');
    						$objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));
    						$objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));
    					$objWriter->endElement();
                    }


    Когда создаем объект добавляем это:

    $objDrawing->setWidth($width);
    $objDrawing->setHeight($height);
    $objDrawing->setResizeProportional(true); 
    $objDrawing->setWidthAndHeight($width,$height);
    Ответ написан
    1 комментарий
  • С чего начать при изучении symfony с нуля?

    alex_dm
    @alex_dm
    Лучше всего начинать здесь:
    https://knpuniversity.com/tracks/symfony
    первый курс бесплатный, если понравится, доступ к остальным 24$/месяц.
    Ответ написан
    Комментировать
  • Как проверить мощность/скорость/канал сервера?

    DreamSoft
    @DreamSoft
    Ведущий системный инженер.
    Утилита dstat покажет сразу все текущие основные параметры сервера.
    Ответ написан
    1 комментарий
  • Как через Nginx скрыть реальный путь к файлу?

    bigton
    @bigton
    Web-программист
    Ответ написан
    Комментировать
  • Отваливается php-fpm с сегфолтом libresolv-2.19.so, как поправить?

    PavelK
    @PavelK Автор вопроса
    Проблему решил принудительно обновив libnss_dns
    Ответ написан
    Комментировать
  • Как правильно организовать и создать проект на Symfony 3?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Комментировать
  • С какими проблемами можно столкнутся при попытке в nginx настроить на работу с 5000 доменами?

    pomeo
    @pomeo
    С Let's Encrypt у вас ничего не получится. Там можно создавать с одного сервера 7 сертификатов в неделю, а для одного домена 5 в неделю. Т.е. за 3 месяца вы для поддоменов максимум сможете ~60 сертификатов получить
    Ответ написан
    9 комментариев
  • Как настроить SSL на NGINX, чтобы получить оценку A в ssllabs.com?

    partizanes
    @partizanes
    Системный Администратор
    Ранг A+

    Конфиг Nginx:
    ssl_certificate      /etc/nginx/ssl/1_.crt;
    ssl_certificate_key  /etc/nginx/ssl/2_.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    	
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    	
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    
    ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    
    add_header Strict-Transport-Security max-age=15768000;


    Версия OpenSSL
    1.0.1e-fips 11 Feb 2013

    dhparam.pem
    openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048


    Сертификат
    WoSign CA Free SSL Certificate G2
    Ответ написан
    5 комментариев
  • Есть ли программа для синхронизации c FTP локальной папки?

    Apathetic
    @Apathetic
    Frontend
    WinSCP (ссылка ведет непосредственно на запрашиваемую фичу)
    Работает через SSH (SCP), WebDAV и FTP.
    Ответ написан
    Комментировать
  • Как в phpStrom 8 правильно обозначить/задать в настройках директории для проекта на Symfony 1,2, чтобы IDE видела папку фреймворка?

    riky
    @riky
    Laravel
    Как уже с казали правильнее фрейм в проекте держать.

    но если хотите как у вас то можно добавить в External libraries (внизу дерева проекта)
    Ответ написан
    Комментировать