Esempio n. 1
0
        protected override async Task ProcessMessage(Message <string, string> message)
        {
            var @event = GrainStateModifyingEvent.Deserialize(message.Value);

            if (GrainProviders.TryGetValue(@event.GrainType, out var provider))
            {
                var grain = (IStateProjectorGrain)provider(GrainFactory, @event.GrainKey);

                await _waitPolicy.ExecuteAsync(
                    async (cancellationToken, context) =>
                {
                    var currentVersion = await grain.GetCurrentVersionAsync();

                    return(currentVersion == @event.GrainVersion);
                },
                    new Dictionary <string, object>
                {
                    { EventTypeContextKey, nameof(GrainStateModifyingEvent) },
                    { GrainTypeContextKey, @event.GrainType },
                    { GrainKeyContextKey, @event.GrainKey },
                    { GrainVersionContextKey, @event.GrainVersion },
                },
                    CancellationToken.None,
                    true);

                await grain.ProjectStateAsync();
            }
            else
            {
                throw new ApplicationException(
                          $"Unknown grain type {@event.GrainType} used in {nameof(GrainStateModifyingEvent)}. " +
                          $"Please check {nameof(DataProjectionDispatchingGrain)} configuration.");
            }
        }
        public async Task Invoke(IIncomingGrainCallContext context)
        {
            var attribute = context.ImplementationMethod.GetCustomAttribute <StateModificationAttribute>();

            if (attribute != null)
            {
                if (context.Grain is IStateProjectorGrain stateProjectorGrain)
                {
                    var grainType    = context.ImplementationMethod.DeclaringType.FullName;
                    var grainKey     = context.Grain.GetPrimaryKeyLong();
                    var grainVersion = await stateProjectorGrain.GetCurrentVersionAsync();

                    var @event  = new GrainStateModifyingEvent(grainType, grainKey, grainVersion);
                    var message = @event.Serialize();

                    var messageKey = $"{grainType}|{grainKey}";
                    await _messageSender.SendAsync(_kafkaOptions.DataProjectionDispatchingTopic, messageKey, message);
                }
            }

            await context.Invoke();
        }