public override void Execute(
            TriggerReactionRegistrationOp operation)
        {
            operation.MustForArg(nameof(operation)).NotBeNull();

            try
            {
                var reactionRegistration =
                    this.reactionRegistrationStream.GetLatestObjectById <string, ReactionRegistration>(operation.ReactionRegistrationId);

                var evaluateReactionRegistrationOp     = new EvaluateReactionRegistrationOp(reactionRegistration, true);
                var evaluateReactionRegistrationResult = this.evaluateReactionRegistrationProtocol.Execute(evaluateReactionRegistrationOp);
                if (evaluateReactionRegistrationResult.ReactionEvent != null)
                {
                    var reaction = evaluateReactionRegistrationResult.ReactionEvent;

                    this.reactionStream.PutWithId(reaction.Id, reaction, reaction.Tags);

                    // once we have recorded the reaction then we can finalize the handling cycle.
                    foreach (var recordSetHandlingMemento in evaluateReactionRegistrationResult.RecordSetHandlingMementos)
                    {
                        recordSetHandlingMemento.CompleteSet();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ReactorException(Invariant($"Failed to trigger {nameof(ReactionRegistration)} Id: {operation.ReactionRegistrationId}."), ex, operation);
            }
        }
        public override IReadOnlyDictionary <string, IReadOnlyDictionary <long, HandlingStatus> > Execute(
            GetReactionRegistrationDependenciesStatusOp operation)
        {
            operation.MustForArg(nameof(operation)).NotBeNull();

            var reactionRegistration = operation.ReactionRegistration;

            if (reactionRegistration.Dependencies.Count != 1)
            {
                throw new NotSupportedException(
                          Invariant(
                              $"Only 1 single {typeof(RecordFilterReactorDependency)} is supported, {reactionRegistration.Dependencies.Count} were supplied."));
            }

            var dependency             = reactionRegistration.Dependencies.Single();
            var recordFilterDependency = dependency as RecordFilterReactorDependency;

            if (recordFilterDependency == null)
            {
                throw new NotSupportedException(
                          Invariant($"Only {typeof(RecordFilterReactorDependency)} is supported, {dependency?.GetType().ToStringReadable()}."));
            }

            var result = new Dictionary <string, IReadOnlyDictionary <long, HandlingStatus> >();

            foreach (var recordFilterEntry in recordFilterDependency.Entries)
            {
                var concern             = EvaluateReactionRegistrationOp.BuildHandlingConcern(reactionRegistration, recordFilterEntry);
                var getHandlingStatusOp = new StandardGetHandlingStatusOp(
                    concern,
                    recordFilterEntry.RecordFilter,
                    new HandlingFilter());
                var stream =
                    (IStandardStream)reactionOperationStreamFactory.Execute(new GetStreamFromRepresentationOp(recordFilterEntry.StreamRepresentation));
                stream.MustForOp(nameof(stream))
                .BeAssignableToType <ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> > >();
                var streamProtocol = (ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> >)stream;
                var handlingStatusesForDependency = streamProtocol.Execute(getHandlingStatusOp);
                result.Add(recordFilterEntry.Id, handlingStatusesForDependency);
            }

            return(result);
        }
예제 #3
0
        public override void Execute(
            RunReactorOp operation)
        {
            operation.MustForArg(nameof(operation)).NotBeNull();

            var getDistinctStringSerializedIdsOp = new StandardGetDistinctStringSerializedIdsOp(
                new RecordFilter(
                    objectTypes: new[]
            {
                typeof(ReactionRegistration).ToRepresentation(),
            },
                    deprecatedIdTypes: new[]
            {
                operation.DeprecatedIdentifierType
            }));
            var distinctIds = this.reactionRegistrationStream.Execute(getDistinctStringSerializedIdsOp);

            Parallel.ForEach(distinctIds,
                             new ParallelOptions {
                MaxDegreeOfParallelism = operation.DegreesOfParallelismForDependencyChecks
            },
                             distinctId =>
            {
                var found = ReactionRegistrationIdToNextEvaluationCutoffMap.TryGetValue(distinctId, out var nextEvaluationCutoff);

                if (!found || DateTime.UtcNow > nextEvaluationCutoff)
                {
                    try
                    {
                        var getLatestRecordOp = new StandardGetLatestRecordOp(
                            new RecordFilter(
                                ids: new[]
                        {
                            distinctId,
                        }));

                        var reactionRegistrationRecord = this.reactionRegistrationStream.Execute(getLatestRecordOp);
                        reactionRegistrationRecord
                        .Payload
                        .PayloadTypeRepresentation
                        .RemoveAssemblyVersions()
                        .MustForOp("recordFromReactionRegistrationStreamExpectedToBeRegisteredReaction")
                        .BeEqualTo(ReactionRegistrationTypeRepWithoutVersion);

                        var reactionRegistration =
                            reactionRegistrationRecord.Payload.DeserializePayloadUsingSpecificFactory <ReactionRegistration>(
                                this.reactionRegistrationStream.SerializerFactory);

                        var evaluateReactionRegistrationOp     = new EvaluateReactionRegistrationOp(reactionRegistration);
                        var evaluateReactionRegistrationResult =
                            this.evaluateReactionRegistrationProtocol.Execute(evaluateReactionRegistrationOp);
                        if (evaluateReactionRegistrationResult.ReactionEvent != null)
                        {
                            var reaction = evaluateReactionRegistrationResult.ReactionEvent;

                            this.reactionStream.PutWithId(reaction.Id, reaction, reaction.Tags);

                            // once we have recorded the reaction then we can finalize the handling cycle.
                            foreach (var recordSetHandlingMemento in evaluateReactionRegistrationResult.RecordSetHandlingMementos)
                            {
                                recordSetHandlingMemento.CompleteSet();
                            }
                        }

                        var newNextEvaluationCutoff = DateTime.UtcNow.Add(reactionRegistration.IdealWaitTimeBetweenEvaluations);
                        ReactionRegistrationIdToNextEvaluationCutoffMap.AddOrUpdate(
                            distinctId,
                            newNextEvaluationCutoff,
                            (_, __) => newNextEvaluationCutoff);
                    }
                    catch (Exception ex)
                    {
                        throw new ReactorException(
                            Invariant($"Failed to process {nameof(ReactionRegistration)} Id: {distinctId}."),
                            ex,
                            operation);
                    }
                }
            });
        }
예제 #4
0
        public override void Execute(
            CompleteHandlingOnReactionRegistrationDependenciesOp operation)
        {
            operation.MustForArg(nameof(operation)).NotBeNull();

            var reactionRegistration = operation.ReactionRegistration;
            var tags = reactionRegistration.Tags?.Any() ?? false
                ? reactionRegistration.Tags.DeepClone().Concat(this.handlingTags?.DeepClone() ?? new NamedValue <string> [0]).ToList()
                : this.handlingTags;

            if (reactionRegistration.Dependencies.Count != 1)
            {
                throw new NotSupportedException(
                          Invariant(
                              $"Only 1 single {typeof(RecordFilterReactorDependency)} is supported, {reactionRegistration.Dependencies.Count} were supplied."));
            }

            var dependency             = reactionRegistration.Dependencies.Single();
            var recordFilterDependency = dependency as RecordFilterReactorDependency;

            if (recordFilterDependency == null)
            {
                throw new NotSupportedException(
                          Invariant($"Only {typeof(RecordFilterReactorDependency)} is supported, {dependency?.GetType().ToStringReadable()}."));
            }

            foreach (var recordFilterEntry in recordFilterDependency.Entries)
            {
                var concern             = EvaluateReactionRegistrationOp.BuildHandlingConcern(reactionRegistration, recordFilterEntry);
                var getHandlingStatusOp = new StandardGetHandlingStatusOp(
                    concern,
                    recordFilterEntry.RecordFilter,
                    new HandlingFilter(CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses));
                var stream =
                    (IStandardStream)reactionOperationStreamFactory.Execute(new GetStreamFromRepresentationOp(recordFilterEntry.StreamRepresentation));
                stream.MustForOp(nameof(stream))
                .BeAssignableToType <ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> > >();
                var streamProtocol = (ISyncReturningProtocol <StandardGetHandlingStatusOp, IReadOnlyDictionary <long, HandlingStatus> >)stream;
                var handlingStatusesForDependency = streamProtocol.Execute(getHandlingStatusOp);
                var missingHandlingMap            = handlingStatusesForDependency
                                                    .Where(
                    _ => CompleteHandlingOnReactionRegistrationDependenciesOp
                    .HandlingStatusesToRegardAsIncomplete.Contains(_.Value))
                                                    .ToDictionary(k => k.Key, v => v.Value);
                if (missingHandlingMap.Any())
                {
                    foreach (var item in missingHandlingMap)
                    {
                        if (!operation.AcceptableHandlingStatuses.Contains(item.Value))
                        {
                            var acceptableStatusesString = operation.AcceptableHandlingStatuses.Select(_ => _.ToString()).ToCsv();
                            throw new InvalidOperationException(Invariant($"Record '{item.Key}' in stream '{stream.Name}' has status '{item.Value}' which is not in the acceptable status list from the operation: {acceptableStatusesString}."));
                        }

                        var completeOp = new StandardUpdateHandlingStatusForRecordOp(
                            item.Key,
                            concern,
                            HandlingStatus.Completed,
                            new[]
                        {
                            HandlingStatus.Running,
                        },
                            operation.Details,
                            tags);

                        var runningOp = new StandardUpdateHandlingStatusForRecordOp(
                            item.Key,
                            concern,
                            HandlingStatus.Running,
                            CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses,
                            operation.Details,
                            tags);

                        if (CompleteHandlingOnReactionRegistrationDependenciesOp.AvailableStatuses.Contains(item.Value))
                        {
                            stream.Execute(runningOp);
                            stream.Execute(completeOp);
                        }
                        else if (item.Value == HandlingStatus.Running)
                        {
                            stream.Execute(completeOp);
                        }
                        else
                        {
                            throw new NotSupportedException(Invariant($"Record '{item.Key}' in stream '{stream.Name}' has status '{item.Value}' which cannot be reset."));
                        }
                    }
                }
            }
        }