Задать вопрос
  • "Удаление" агрегата в DDD?

    @phenya Автор вопроса
    спасибо за решение с сохранением событий и наводку на Saga Orchestration, при беглом просмотре выглядит как неплохое решение для сохранения атомарности
  • "Удаление" агрегата в DDD?

    @phenya Автор вопроса
    Максим Федоров,
    такого в вашем бизнесе нет


    есть, еще как есть.

    Есть каталоги товаров, они себе нормально работают, всех всё устраивает. Дальше бизнес говорит, а давайте интегрируемся с внешней ERP, чтобы можно было элементы каталогов получать напрямую из ERP, только нужно сделать сопоставление сущностей оттуда с сущностями из наших каталогов. Как это сделать? Нужно создать ограниченный контекст отдельно от нашего смыслового ядра, с каталогами, товарами и прочим. Сказано, сделано - создан ограниченный контекст с агрегатом Integration

    Integration: IntegrationId, Name, EntityRelation[]
    EntityRelation: IntegrationId, EntityType, InternalId, ExternalId
    Пример
    Integration: 'sap', 'SAP Integration', []
    EntityRelation: 'sap', 'catalog', 'books', 'H13kkhj-lkj21JI'

    В этом случае Catalog ничего не знает об Integration и наоборот(только на уровне метаданных). Никаких общих связей у них нет. А всё их взаимодействие происходит на уровне отдельного сервиса приложения, который занимается обменом с внешней ERP;
    С другой стороны при удалении каталога (Catalog), должны удалиться и их интеграционные связи, те самые EntityRelation; Связь между разными контекстами можно реализовать с помощью событий. И это легко сделать. Но вот как Catalog узнает, что он сейчас удаляется, чтобы инициировать событие, если мы его удаляем через хранилище, которое не содержит в себе ни капли бизнес-логики и тем более не может знать, что существуют какие-то интеграции.
    Возможно вместо того, что я писал выше сделать как то так:

    class Catalog extends AbstractEntity
    {
       private $removed = false;
       ...
       public function isRemoved()
       {
           return $this->removed;
       }
    
       public function remove()
       {
          $this->removed = true;
          $eventManager->dispatch(new CatalogDeleted($this->id()));
       }
       ...
    }
    
    class CatalogRepository extends AbstractRepository implements CatalogRepositoryInterface
    {
       ...
       public function update(Catalog $catalog)
       {
           if($catalog->isRemoved()){
              $this->delete($catalog);
           }
       }
       
       private function delete(Catalog $catalog)
       {
           //удаляем из базы
       }
    }
    
    //Client
    $catalog->remove(); //каталог всем сообщает, что он сейчас будет удален (удаляются интеграционные связи)
    $repository->update($catalog); //удаляется каталог из БД


    Но вот как теперь обеспечить атомарность(транзакционность) такой операции (удаление каталога + удаление интеграционных связей), учитывая, что Integration находится в другом контексте.
  • Связка exec() + mysqli_query(), что тут вообще происходит?

    @phenya Автор вопроса
    Сергей Сергей: спасибо, за предложенные варианты )

    после запроса уже ничего не выполняется, даже если след. строчкой будет die('1'); он не выполнится )
    костыль уровня "кресло-каталка" мог бы помочь в случае абстрактных примеров приведенных в описании, но не в реальном проекте, потому-что выполнение скрипта №1 обрывается где-то в одном из многочисленных модулей, подключаемых до начала выполнения основной логики 1-го скрипта (авторизация, сбор статистики, логирование запросов).
    Т.е. я хочу донести, что для воспроизведения такого поведения достаточно этих 2 надуманных примеров. Но при этом реальный проект намного больше и там костылями не обойтись (иначе я бы их уже давно поставил )) )
    Сегодня попробую накатить проект на более свежую сборку с php 7.0 и mysqlnd 5.0.12 версией, потому-что сдается мне, что это баг именно на уровне ядра самого php
  • Связка exec() + mysqli_query(), что тут вообще происходит?

    @phenya Автор вопроса
    переменные окружения одинаковые. Костыли не подходят, потому-что после запроса должно выполняться еще очень много всего ), а mysqli_query просто вылетает обрывая скрипт. Тут такое ощущение, что где-то в самом интерпретаторе php вываливается какой-то segmentation fail и все обрывается
  • Связка exec() + mysqli_query(), что тут вообще происходит?

    @phenya Автор вопроса
    примеры в описании - упрощенные, я их привел только для лучшего понимания сути взаимодействия 2-х скриптов в результате которого проявляется такое поведение функции mysqli_query вызванной в скрипте, запущенном через exec.
  • Связка exec() + mysqli_query(), что тут вообще происходит?

    @phenya Автор вопроса
    Сергей Сергей:
    в рамках реальной задачи не получится, в реальном проекте
    1-й скрипт: скрипт обработки очереди, должен запускаться в фоновом режиме
    2-й скрипт, контроллер управления 1-м скриптом посредством http (но первый может запускаться и кроном)
  • Связка exec() + mysqli_query(), что тут вообще происходит?

    @phenya Автор вопроса
    Павел Волынцев: нет, с этим все впорядке - всё выполняется, пути в оригинальном скрипте абсолютные. Проблема именно в выполнении mysqli_query() вызванной в скрипте, запущенном через exec
  • Decorator реализующий интерфейс, а не конкретный класс, возможно ли?

    @phenya Автор вопроса
    Mercury13: да, но нормально не будет :), потому-что у нас тут не наследование, а композиция. Мы Декоратор реализуем от интерфейса, но не наследуем от реализации(как обычно и поступают с Декораторам) отсюда вся проблема как раз
  • Как добавить пробелы между букв?

    @phenya
    занудства ради, такая функция будет работать для любых символов, а в задаче речь шла о буквах )
  • Decorator реализующий интерфейс, а не конкретный класс, возможно ли?

    @phenya Автор вопроса
    нет, сигнатура везде одинаковая, и не важна, если что-то в описании задачи упустил, то только в описании, чтобы не расписывать много. А проблема в том, что если я в ValidationRepository::create($model) вызову $this->repository->create($model), то он и вызовется в контексте $this->repository, у которого есть своя функция save() без валидации.