Каков предлагаемый подход для проверки команд в Akka? - PullRequest
0 голосов
/ 19 мая 2018

Допустим, у меня есть следующий сценарий.Есть UserActor.Помимо тривиальных свойств, таких как Id, FirstName, LastName, внутреннее состояние пользователя содержит CategoryId, который представляет приверженность пользователя определенной категории.Сама категория представляет собой отдельную сущность домена, которая имеет свои собственные свойстваЧтобы выполнить операцию присвоения пользователю определенной категории, я должен убедиться, что конкретная категория действительно существует.Как правильно обращаться с такими сценариями, которые гарантируют согласованность системы?

Я думаю о двух решениях, но я не уверен, какое из них хуже другого.

  1. Игнорировать правило «скажи, не спрашивай» и запросить CategoriesActor, используя протокол Ask, чтобы определить, существует ли категория с указанным Id?
  2. Создать какой-то вспомогательный актор (ValidatorActor), который выполняет все необходимые проверкии ответ с результатом для UserActor.Тем временем, UserActor изменит свое состояние на sth, например «Ожидание результатов команды», и будет складывать все входящие сообщения до тех пор, пока не будут получены правильные результаты проверки команды.

Первое решение отрицает все, во что я верю.Второе не слишком хорошо масштабируется с точки зрения распространения класса / актеров.Более того, если UserActor является постоянным FSM, я понятия не имею, как вернуться из этого лимба «ожидания результатов проверки команд».Для ФСМ нет эквивалента Unbecome.

Я полагаю, что если вы используете Akka вместе с подходом CQRS / ES, вы должны решить подобные проблемы.Как вы к ним обратились?Я прочитал несколько книг об Акке и не нашел никакого самоуверенного подхода.Это странно, потому что, на мой взгляд, это такой фундаментальный вариант использования.

Я был бы очень признателен за любые подсказки.

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Я слегка сгибаю правило "говори, не спрашивай".Методы получения и команды в Akka.net имеют необязательный предикат с именем shouldHandle.Я делаю ask, но делаю Sender.Tell() внутри метода shouldHandle.Если результат предиката равен false, указанное вами действие не будет выполнено.

Пример кода:

public MyActor
{
    Command<Object>(cmd => HandleObject(cmd), cmd => ValidateObject(cmd));
}

private bool ValidateObject(Object cmd)
{
    // Perform validation as necessary... isValid could be anything but needs to be set
    if(isValid)
    {
        Sender.Tell(true);
        return true;
    }
    else
    {
        Sender.Tell(false);
        return false;
    }
}

private void HandleObject(Object cmd)
{
    // Handle command
}

В приведенном выше коде HandleObject никогда не будет выполняться, если только ValidateObject возвращает истину.Этот шаблон работает как для ask, так и для tell.Единственная причина, по которой я выполняю ask, заключается в том, что мне нужно уведомить пользователя, если команда не проходит проверку ... в противном случае я бы использовал tell, не беспокоясь о выполнении Sender.Tell.

0 голосов
/ 19 мая 2018

Вы пытаетесь предотвратить недопустимое состояние системы, которое может произойти в любое время.Категория может быть удалена в любое время после того, как Пользователь ее придерживается.

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

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

Игнорируйте правило «говорите, не спрашивайте», и запрашивайте CategoriesActor, используя протокол Ask, чтобы определить, существует ли категория с указанным Id или нет?

Это правило не применяется здесь, но в ситуациях, когда вы запрашиваете у актера что-то, а затем говорите тому же актеру сделать что-то на основе того, что он вам сказал.

PS Я предположил, что у вас есть распределенная система, потому что вы решили использовать модель Actor.

...