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); }
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); } } }); }
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.")); } } } } }