/// <summary> /// Initializes a new instance of the <see cref="OperationManager{TSessionState, TOperationState}"/> class. /// </summary> /// <param name="sessionId">Session id.</param> /// <param name="sessionState">Initial session state.</param> /// <param name="sessionManager">Owner session manager.</param> /// <param name="executionOptions">Optional execution options. Also can be provided in Start method.</param> /// <param name="logger">Logger.</param> /// <param name="metadata">Optional metadata.</param> public OperationManager( OperationId sessionId, [DisallowNull] TSessionState sessionState, ISessionManager <TSessionState, TOperationState> sessionManager, IExecutionOptions <TSessionState, TOperationState>?executionOptions = null, ILogger?logger = null, IPropertyContainer?metadata = null) { sessionState.AssertArgumentNotNull(nameof(sessionState)); sessionManager.AssertArgumentNotNull(nameof(sessionManager)); _sessionManager = sessionManager; _logger = logger ?? GetLoggerFactory().CreateLogger(sessionId.Value); _operations = new ConcurrentDictionary <OperationId, IOperation <TOperationState> >(); _session = Operation .CreateNotStarted(sessionId, sessionState, metadata) .ToSession(getOperations: GetOperations); if (executionOptions != null) { _session = _session.With(executionOptions: executionOptions); } ILoggerFactory GetLoggerFactory() => (ILoggerFactory?)_sessionManager.Services.GetService(typeof(ILoggerFactory)) ?? NullLoggerFactory.Instance; }
public bool Validate(IExecutionOptions options) { if (options.Files == null) { throw new ApplicationException("Files not specified."); } if (options.Files.Length == 0) { throw new ApplicationException("Files not specified."); } if (options.Logger == null) { throw new ApplicationException("Logger not specified."); } if (options.ResultsFormatter == null) { throw new ApplicationException("Results formatter not specified."); } foreach (var file in options.Files.Where(file => !File.Exists(file))) { throw new FileNotFoundException(string.Format("Assembly file {0} not found.", file)); } return(true); }
/// <summary> /// Engine distructor. /// </summary> /// <param name="options">The options to use.</param> /// <exception cref="System.ArgumentNullException"></exception> public Engine(IExecutionOptions options) { if (options == null) { throw new ArgumentNullException("options"); } _options = options; }
/// <inheritdoc /> public async Task Start(IExecutionOptions <TSessionState, TOperationState>?executionOptions = null) { if (_runtime != null) { throw new OperationManagerException(Errors.SessionIsAlreadyStarted(_session.Id)); } if (_session.ExecutionOptions is IExecutionOptions <TSessionState, TOperationState> sessionExecutionOptions) { // Merge params provided on initialization and on start. executionOptions = new ExecutionOptions <TSessionState, TOperationState>() { MaxConcurrencyLevel = executionOptions?.MaxConcurrencyLevel ?? sessionExecutionOptions.MaxConcurrencyLevel ?? Environment.ProcessorCount, SessionTimeout = executionOptions?.SessionTimeout ?? sessionExecutionOptions.SessionTimeout ?? TimeSpan.FromHours(24), Executor = executionOptions?.Executor ?? sessionExecutionOptions.Executor, ExecutorExtended = executionOptions?.ExecutorExtended ?? sessionExecutionOptions.ExecutorExtended, OnOperationFinished = executionOptions?.OnOperationFinished ?? sessionExecutionOptions.OnOperationFinished, OnSessionFinished = executionOptions?.OnSessionFinished ?? sessionExecutionOptions.OnSessionFinished, CancellationToken = executionOptions?.CancellationToken ?? CancellationToken.None, }; } if (executionOptions == null) { throw new ArgumentNullException(nameof(executionOptions), "Provide executionOptions on start or initialization."); } if (executionOptions.ExecutorExtended == null && executionOptions.Executor == null) { throw new ArgumentException($"ExecutionOptions: {nameof(executionOptions.ExecutorExtended)} or {nameof(executionOptions.Executor)} should be provided.", nameof(executionOptions)); } if (executionOptions.ExecutorExtended != null && executionOptions.Executor != null) { throw new ArgumentException($"ExecutionOptions: Only one of {nameof(executionOptions.ExecutorExtended)}, {nameof(executionOptions.Executor)} should be provided.", nameof(executionOptions)); } using var updateLock = await _updateLock.WaitAsyncAndGetLockReleaser(); _session = _session.With( status: OperationStatus.InProgress, startedAt: DateTime.Now.ToLocalDateTime(), executionOptions: executionOptions); var cts = CreateCancellation(executionOptions); var pipeline = new Pipeline <IOperation <TOperationState> >() .AddStep(operation => ProcessOperation(operation), settings => { settings.MaxDegreeOfParallelism = executionOptions.MaxConcurrencyLevel !.Value; settings.ExecutionOptions.CancellationToken = cts.Token; })
public Runtime( IExecutionOptions <TSessionState, TOperationState> options, CancellationTokenSource cts, Pipeline <IOperation <TOperationState> > pipeline, SessionTracer sessionTracer, Func <Task, ISession <TSessionState, TOperationState> > onSessionFinished) { Options = options; Cts = cts; Pipeline = pipeline; SessionTracer = sessionTracer; _onSessionFinished = onSessionFinished; }
public ExecutionContext(IExecutionOptions executionOptions, IValidatorsFactory validatorsFactory) { CollectionForceKey = executionOptions.CollectionForceKey; RequiredError = executionOptions.RequiredError; DefaultError = executionOptions.DefaultError; MaxDepth = executionOptions.MaxDepth; ValidatorsFactory = validatorsFactory; _defaultErrorCollection = new Lazy <ErrorsCollection>(() => { if (DefaultError == null) { return(null); } var defaultErrorCollection = new ErrorsCollection(); defaultErrorCollection.AddError(DefaultError); return(defaultErrorCollection); }); }
/// <summary> /// Disposes the Engine. /// </summary> public void Dispose() { _options = null; _validator = null; }
// ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local private static IModelReport BuildModelReport(IErrorsCollection errorsCollection, Translator translator, int depth, IExecutionOptions executionOptions) { if (depth > executionOptions.MaxDepth) { throw new MaxDepthExceededException(executionOptions.MaxDepth); } if (errorsCollection.IsEmpty) { return(ModelReport.Empty); } var errorsList = new ModelReportErrorsList(); if (errorsCollection.Errors.Any()) { var errors = errorsCollection.Errors .Select(e => translator(e)) .Distinct() .ToList(); errorsList.AddRange(errors); } if (!errorsCollection.Members.Any()) { return(errorsList); } var report = errorsList.Any() ? new ModelReport { { string.Empty, errorsList } } : new ModelReport(); foreach (var memberPair in errorsCollection.Members) { var memberReport = BuildModelReport(memberPair.Value, translator, depth + 1, executionOptions); if (memberReport != null) { report.Add(memberPair.Key, memberReport); } } return(report); }
static ExecutionFlow() { Options = new ExecutionOptions(); }
internal ValidationResult(Guid validationContextId, ITranslationProxy translationProxy, IExecutionOptions executionOptions, T model = null, IErrorsCollection errorsCollection = null) { TranslationProxy = translationProxy ?? throw new ArgumentNullException(nameof(translationProxy)); ErrorsCollection = errorsCollection ?? Errors.ErrorsCollection.Empty; ExecutionOptions = executionOptions ?? throw new ArgumentNullException(nameof(executionOptions)); ValidationDate = DateTime.UtcNow; ValidationContextId = validationContextId; Model = model; }
// ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local private static void BuildListReport(ListReport listReport, string path, IErrorsCollection errorsCollection, Translator translator, int depth, IExecutionOptions executionOptions) { if (depth > executionOptions.MaxDepth) { throw new MaxDepthExceededException(executionOptions.MaxDepth); } if (errorsCollection.IsEmpty) { return; } if (errorsCollection.Errors.Any()) { listReport.AddRange(errorsCollection.Errors .Select(m => string.IsNullOrWhiteSpace(path) ? translator(m) : $"{path}: {translator(m)}") .Distinct() .ToList() ); } foreach (var memberPair in errorsCollection.Members) { var currentPath = string.IsNullOrEmpty(path) ? string.Empty : $"{path}."; BuildListReport(listReport, $"{currentPath}{memberPair.Key}", memberPair.Value, translator, depth + 1, executionOptions); } }