Обновить
4
0
Александр @BoShurik

Symfony-разрботчик

Отправить сообщение

Во-первых, вы выбрали это решение потому что у вас уже были наработки. Думаю большинство разработчиков поступили бы так же и были бы правы.


В случае, если таких наработок нет, я и предложил свой вариант.


В идеальном случае будет что-то вроде:


composer req symfony/messenger symfony/mailer symfony/notifier
composer req symfony/*-mailer symfony/*-notifier

Останется только прописать конфиги, выставить в supervisor'e нужное количество воркеров и все. Ни строчки кода от разработчика не понадобится. (это к вопросу о том что я уйду и оставлю после себя нечто неподдерживаемое, при том что у вас кода выходит больше)


Если нужного транспорта нет, то да, придется его реализовать (как, впрочем, и в вашем случае), что в общем-то тривиально (e.g. symfony/free-mobile-notifier)


1) простую очередь (замечу, что ее можно использовать не только для рассылок)
2) изолированный микросервис для рассылок (легковесный, 8мб в докере)
3) используем go либу для амазона, и пишем GET/POST запрос для отправки СМС куда душе угодно
У вас же 2 библиотеки минимум + та же самая очередь потребуется (для асинхронной рассылки) + также надо имплементацию писать.

Плюс-минус одинаково, разве нет? В моем варианте используются абстракции в рамках php, а в вашем — конкретные библиотеки для конкретных решений, разнесенные по разным языкам.


В вашем же кейсе возникают вопросы — как прикрутить 2 аккаунта, как добавить рейт лимитер. Как прикрутить рейт лимитер к рассыльщику и т.п.
Так ваш проект начнет уже на старте обрастать тех долгом, костылями.

Несколько аккаунтов идут из коробки, рейт лимит решается элементарными декораторами (да, не так красиво, как, возможно, у вас, но и не костыли). Не понимаю, правда, почему вы считаете, что эти же требования не добавят костыли и тех. долг в ваше решение, но добавят в мое.


Решение из коробки это классно, но только если вы на 100% уверены что не придется его масштабировать.

По факту вам не понадобился ни рейт лимитер, ни 2 аккаунта, т.е. в рамках задачи можно было бы использовать и решение из коробки :)

Очень быстро авторизацию через соц.сети можно интегрировать, добавив в проект библиотеку LexikJWTAuthenticationBundle.

А можно подробней. Все-таки LexikJWTAuthenticationBundle provides JWT (Json Web Token) authentication for your Symfony API. Про соц. сети в документации ни слова.


Случайно не HWIOAuthBundle имелся в виду?

Да и как я понимаю, в том компоненте не поддержан абсолютно любой СМС шлюз?

Они легко добавляются (надо имплементировать соответствующий интерфейс)
Пока компонент эксперементальный, но, думаю, со временем обрастет сторонними транспортами

А если вам потребуется отсылать еще и СМС и пуш уведомления?

То можно взять symfony/notifier

Почему выбрали именно PHP -> NATS -> GO -> Amazon SES?
symfony/mailer умеет в очереди и поддерживает Amazon SES

Даже не раздуты, а их нельзя было реализовать в актуальных на тот момент компонентах (symfony/http-foundation, doctrine/cache etc), т.е. это никак не interoperability group.
Вот тут выжимка: https://hub.packtpub.com/symfony-leaves-php-fig-the-framework-interoperability-group/

К сожалению, статья уже не актуальна:


Внимание! В связи с прекращением поддержки SAML 2.0 в ЕСИА подключение ИС к ЕСИА через этот интерфейс будет прекращено с 01.01.2018 г., поэтому для подключения рекомендуется использовать протокол OAuth 2.0 / OpenID Connect. Запрещено подключение по протоколу SAML 2.0 и по протоколу OAuth 2.0 / OpenID Connect одновременно. Возможность изменения параметров подключения к ЕСИА через интерфейс SAML 2.0 для ранее подключенных ИС будет сохранена.

Я к тому, что, мне кажется, эта задача решается проще, выделением блока try-catch в отдельный процесс, т.о. ошибки в одной из задач не будут влиять на другие. Что-то вроде


while (!$this->isShuttingDown()) {
    $task = $this->taskProvider->getNextTask();

    // fire and forget
    $this->producer->runTask($task);
}

Почему отказались от использования очередей? В случае, если одна задача — один процесс, проблем бы с менеджером не было

Потому что реализаторы А должны принимать любой инстанс интерфейса Б, а не одну отдельную его реализацию.

Мне кажется, вы не обратили внимание на мой пример. Там нет отдельной реализации интерфейса Б, он заменен на более общий object, т.о. все клиенты InterfaceA смогут безболезненно использовать InterfaceB в качестве аргумента. В свою очередь клиенты ClassA смогут использовать любой объект

А в чем проблема расширения интерфейса?


`ClassA implements InterfaceA {fun do(object $b){}}`

пример принцип Лисков не нарушает, на сколько я его понимаю

Если прогнать ваш код через PHP Mess Detector, он выдает


src/Bitrix.php:12   The method publishOne() has a Cyclomatic Complexity of 43. The configured cyclomatic complexity threshold is 10.
src/Bitrix.php:12   The method publishOne() has an NPath complexity of 7739670528. The configured NPath complexity threshold is 200.

Банальное исправление блока


Код
$gotChild = BitrixOrm::isFetchSuccess($child);
$childId = 0;
$childPermit = 0;
$gotPublicPermit = false;
if ($gotChild) {
    $childId = $child['ID'];
    $childPermit = $child['PROPERTY_PERMIT_OF_AD_VALUE'];
    $gotPublicPermit = !empty($childPermit);
}
$isSuccessDelete = false;
if ($gotPublicPermit) {
    $isSuccessDelete = CIBlockElement::Delete($childPermit);
}
if ($gotPublicPermit && !$isSuccessDelete) {
    $output['message'] = 'Fail delete published permit;';
}
if ($gotPublicPermit && $isSuccessDelete) {
    $output['message'] = 'Success delete published permit;';
}
if ($gotChild) {
    $isSuccessDelete = CIBlockElement::Delete($childId);
}
if ($gotChild && !$isSuccessDelete) {
    $output['message'] = 'Fail delete published permit;';
}
if ($gotChild && $isSuccessDelete) {
    $output['message'] =  'Success delete published permit;';
}

на


Код
if (BitrixOrm::isFetchSuccess($child)) {
    $childId = $child['ID'];
    $childPermit = $child['PROPERTY_PERMIT_OF_AD_VALUE'];
    if (!empty($childPermit)) {
        if (CIBlockElement::Delete($childPermit)) {
            $output['message'] = 'Fail delete published permit;';
        } else {
            $output['message'] = 'Success delete published permit;';
        }
    }
    if (CIBlockElement::Delete($childId)) {
        $output['message'] =  'Success delete published permit;';
    } else {
        $output['message'] = 'Fail delete published permit;';
    }
}

PHPMD уже выдает


src/Bitrix.php:12   The method publishOne() has a Cyclomatic Complexity of 36. The configured cyclomatic complexity threshold is 10.
rc/Bitrix.php:12    The method publishOne() has an NPath complexity of 83607552. The configured NPath complexity threshold is 200.

Тут и код получается короче раза в два и сразу понятно что он делает.
Ощущение, что ваш код перетерпел кучу рефакторинга, потому что выгялдит он ну очень неествественно.

Разве алиаса не будет достаточно?


composer.phar require phpunit/php-code-coverage 'dev-7.0.8-myFix as 7.0.7'

Например, в Symfony данные в куке подписываются с помощью секретного ключа, чтоб их нельзя было подделать

В том же Chrome есть возможность скопировать XPath через панель разработчика. Так что париться не придется

В 7.2.21 это изменение откатили как раз по этой причине

Вот еще интересная issue в Symfony/php 7.4
https://github.com/symfony/symfony/issues/32995
В новое версии php стал бросать Fatal error, если не найден родительский класс/интерфейс
https://3v4l.org/uh8ae

Она разработана без привязки к Symfony

Все-таки yoanm/symfony-jsonrpc-http-server — это бандл для симфони, он очень даже привязан к ней. Речь наверное про yoanm/jsonrpc-server-sdk

Информация

В рейтинге
Не участвует
Откуда
Владимир, Владимирская обл., Россия
Дата рождения
Зарегистрирован
Активность