Реплицированные зерна
Иногда может быть несколько экземпляров одного и того же активного зерна, например при работе с несколькими кластерами и использовании OneInstancePerClusterAttribute. ЖурналedGrain предназначен для поддержки реплика экземпляров с минимальными трениями. Он зависит от поставщиков согласованности журналов для выполнения необходимых протоколов, чтобы убедиться, что все экземпляры согласуются с одной последовательностью событий. В частности, он заботится о следующих аспектах:
Согласованные версии: все версии состояния зерна (за исключением предварительных версий) основаны на одной глобальной последовательности событий. В частности, если два экземпляра видят одинаковый номер версии, то они видят одно и то же состояние.
Гоночные события: несколько экземпляров могут одновременно вызывать событие. Поставщик согласованности разрешает эту гонку и гарантирует, что все согласны с одной последовательностью.
Уведомления и реактивность. После того, как событие возникает в одном экземпляре, поставщик согласованности не только обновляет хранилище, но и уведомляет всех остальных экземпляров зерна.
Общие сведения о согласованности см. в документе TechReport и GSP (глобальный протокол последовательности).
Условные события
Гоночные события могут быть проблематичными, если у них конфликт, т. е. не должны оба фиксации по какой-то причине. Например, при выводе денег с банковского счета два экземпляра могут независимо определить, есть ли достаточные средства для вывода и выдача события вывода. Но сочетание обоих событий может перезарыть. Чтобы избежать этого, JournaledGrain
API поддерживает RaiseConditionalEvent метод.
bool success = await RaiseConditionalEvent(
new WithdrawalEvent() { /* ... */ });
Условные события дважды проверка, если локальная версия соответствует версии в хранилище. Если нет, это означает, что последовательность событий выросла в то же время, что означает, что это событие потеряло гонку против другого события. В этом случае условное событие не добавляется в журнал и RaiseConditionalEvent возвращает значение false.
Это аналог использования электронных тегов с обновлениями условного хранилища, а также простой механизм для предотвращения фиксации конфликтующих событий.
Можно и разумно использовать как условные, так и безусловные события для одного и того же зерна, например a DepositEvent
и a WithdrawalEvent
. Депозиты не должны быть условными: даже если DepositEvent
раса теряет гонку, ее не нужно отменить, но все равно можно добавить к глобальной последовательности событий.
Ожидание возвращаемой RaiseConditionalEvent
задачи достаточно для подтверждения события, т. е. не требуется также вызывать ConfirmEvents
.
Явная синхронизация
Иногда желательно убедиться, что зерно полностью догон до последней версии. Это можно применить путем вызова:
await RefreshNow();
Он выполняет две задачи.
- Он подтверждает все неподтвержденные события.
- Она загружает последнюю версию из хранилища.