// TODO: Put strings into the resources. // protected void CreateActivateControl(out IRunControl <TXAppScopeInstance> control) { TXAppScopeInstance component; try { component = (TXAppScopeInstance)this; } catch (Exception exception) { throw new InvalidCastException( message: $"Ошибка приведения компонента к требуемому типу.{Environment.NewLine}\tКомпонент:{this.FmtStr().GNLI2()}{Environment.NewLine}\tТребуемый тип:{typeof(TXAppScopeInstance).FmtStr().GNLI2()}", innerException: exception); } var appRunControlOptions = App.RunControl.Options; CreateActivateControl( options: DefineDefaultOfActivateControlOptions() | (appRunControlOptions & RunControlOptions.ForbidStart), component: component, attemptState: createAttemptState, beforeActivate: DoBeforeActivateAsync, activate: DoActivateAsync, deactivate: DoDeactivateAsync, deactivationToken: App.ShutdownToken, control: out control); // IRunControlAttemptState createAttemptState(in RunControlAttemptStateFactoryArgs locArgs) { CreateActivateAttemptState(args: in locArgs, state: out var locState); return(locState); } }
public RunControlAttemptLoggingData(IRunControl runControl, bool isStart, int attemptNumber, int succeededAttemptCountBefore, OperationCompletionStatusCode status, TimeSpan duration, Exception exception = default, XFullCorrelationId correlationId = default) : base(runControl: runControl, isStart: isStart, attemptNumber: attemptNumber, succeededAttemptCountBefore: succeededAttemptCountBefore, correlationId: correlationId) { // if (status == OperationCompletionStatusCode.Undefined) { throw new ArgumentOutOfRangeException(paramName: nameof(status)); } else if (duration < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(paramName: nameof(duration)); } else if (status == OperationCompletionStatusCode.Fault) { exception.EnsureNotNull(nameof(exception)); } else { exception.Arg(nameof(exception)).EnsureIsNull(); } // Status = status; Duration = duration; Exception = exception; }
public RunControlAttemptStateFactoryArgs(IRunControl runControl, Task <IRunControlAttemptSuccess> completion, IContext context, bool isStart, int attemptNumber, int succeededAttemptCountBefore, object tag = default) { RunControl = runControl; Completion = completion; Context = context; IsStart = isStart; AttemptNumber = attemptNumber; SucceededAttemptCountBefore = succeededAttemptCountBefore; Tag = tag; }
// TODO: Put strings into the resources. // static async Task <IList <ILocalSubscription> > P_PublicationFilterAsync(IRunControl publisherRunControl, ILocalMessage msg, IList <ILocalSubscription> sourceSubscriptions) { publisherRunControl.EnsureNotNull(nameof(publisherRunControl)); msg.EnsureNotNull(nameof(msg)); sourceSubscriptions.EnsureNotNull(nameof(sourceSubscriptions)); // if (sourceSubscriptions.Count < 1 || publisherRunControl.HasStopRequested) { return(new ILocalSubscription[0]); } else { var sourceSubscriptionsList = new List <ILocalSubscription>(); var length = sourceSubscriptions.Count; for (var offset = 0; offset < length; offset++) { var subscription = sourceSubscriptions[offset]; if (subscription is null) { throw new ArgumentException( paramName: $"{nameof(sourceSubscriptions)}[{offset:d}]", message: FormatXResource(typeof(Array), "CanNotContainNull/NullAt", offset.ToString("d"))); } sourceSubscriptionsList.Add(subscription); } // var filterResultList = new List <ILocalSubscription>(); for (var i = 0; i < sourceSubscriptionsList.Count; i++) { if (publisherRunControl.HasStopRequested) { break; } // var subscription = sourceSubscriptionsList[i]; var subscriptionFilterResult = await subscription.PublicationFilterAsync(state : new LocalPublicationFilterState(message: msg, subscription: subscription)).ConfigureAwait(false); if (!subscriptionFilterResult.CancelPublication) { filterResultList.Add(subscription); } } // if (publisherRunControl.HasStopRequested) { return(new ILocalSubscription[0]); } else { return(filterResultList); } } }
protected override void CreateActivateControl( RunControlOptions options, ResetServant <TDescription> component, RunControlAttemptStateFactory attemptState, Func <IRunControlAttemptState, Task> beforeActivate, Func <IRunControlAttemptState, Task> activate, Func <Task> deactivate, CancellationToken deactivationToken, out IRunControl <ResetServant <TDescription> > control) => control = ReadIA(ref _activateControlFactory, locationName: nameof(_activateControlFactory)) (options : options, component : component, attemptState : attemptState, beforeStart : beforeActivate, start : activate, stop : deactivate, stopToken : deactivationToken);
// TODO: Put strings into the resources. // protected override async Task OnInitializeAsync(IContext ctx = default) { var ct = ctx.Ct(); if (ct.IsCancellationRequested) { throw new OperationCanceledException(token: ct); } else { IRunControl <TXAppScopeInstance> control = default; try { CreateActivateControl(control: out control); if (control is null) { throw new EonException(message: $"Activation control is not created.{Environment.NewLine}\tComponent:{this.FmtStr().GNLI2()}"); } else if (!ReferenceEquals(control.Component, this)) { throw new EonException(message: $"Created activation control is not associated with this component (see property '{nameof(control)}.{nameof(control.Component)}').{Environment.NewLine}\tComponent:{this.FmtStr().GNLI2()}"); } else if (ct.IsCancellationRequested) { control.Dispose(); throw new OperationCanceledException(token: ct); } else { AdjustActivateControl(control: control); if (ct.IsCancellationRequested) { control.Dispose(); throw new OperationCanceledException(token: ct); } else { WriteDA(ref _activateControl, control); if (vlt.Read(ref _hasDeactivatedBeforeInitialization)) { await control.StopAsync(finiteStop : true).ConfigureAwait(false); } } } } catch (Exception exception) { control?.Dispose(exception); throw; } } }
// TODO: Put strings into the resources. // protected RunControlAttemptPropertiesBase(IRunControl runControl, bool isStart, int attemptNumber, int succeededAttemptCountBefore, XFullCorrelationId correlationId = default, object tag = default) { runControl.EnsureNotNull(nameof(runControl)); attemptNumber.Arg(nameof(attemptNumber)).EnsureNotLessThanZero(); succeededAttemptCountBefore.Arg(nameof(succeededAttemptCountBefore)).EnsureNotLessThanZero().EnsureNotGreaterThan(attemptNumber); if (correlationId?.IsEmpty == true) throw new ArgumentException(message: "Value cann't be an empty.", paramName: nameof(correlationId)); // CorrelationId = correlationId; RunControl = runControl; IsStart = isStart; AttemptNumber = attemptNumber; SucceededAttemptCountBefore = succeededAttemptCountBefore; Tag = tag; }
protected virtual void CreateActivateControl( RunControlOptions options, TXAppScopeInstance component, RunControlAttemptStateFactory attemptState, Func <IRunControlAttemptState, Task> beforeActivate, Func <IRunControlAttemptState, Task> activate, Func <Task> deactivate, CancellationToken deactivationToken, out IRunControl <TXAppScopeInstance> control) => control = new RunControl <TXAppScopeInstance>( options: options, component: component, attemptState: attemptState, beforeStart: beforeActivate, start: activate, stop: deactivate, stopToken: deactivationToken);
public RunControlEventArgs(IRunControl runControl) { runControl.EnsureNotNull(nameof(runControl)); // RunControl = runControl; }
async Task <ILocalMessagePostingToken> P_PublishMessageAsync(ILocalMessage msg, bool disposeMessageAtEndOfPosting) { msg.EnsureNotNull(nameof(msg)); // ILocalMessagePostingToken postingToken; IRunControl runControl = ReadDA(ref _runControl); IList <ILocalSubscription> subscriptions = ReadDA(ref _subscriptionsSpinLock).Invoke(() => ReadDA(ref _subscriptionsList).Where(i => i.IsActive).ToArray()); subscriptions = await P_PublicationFilterAsync(publisherRunControl : runControl, msg : msg, sourceSubscriptions : subscriptions).ConfigureAwait(false); if (subscriptions.Count > 0 && !runControl.HasStopRequested) { var postingTokenStricted = new LocalPostingToken(message: msg, postingCount: subscriptions.Count, disposeMessageAtEndOfPosting: disposeMessageAtEndOfPosting); postingToken = postingTokenStricted; var postingQueueEntry = default(LocalPostingQueueEntry); try { postingQueueEntry = new LocalPostingQueueEntry(postingToken: postingTokenStricted, postingSubscriptions: subscriptions); var postingQueueLength = ReadDA(ref _postingQueueSpinLock) .Invoke( () => { var locPostingQueue = ReadDA(ref _postingQueue); locPostingQueue.Enqueue(postingQueueEntry); return(locPostingQueue.Count); }); #if TRG_NETFRAMEWORK if (postingQueueLength >= __PostingQueueLengthWarning) { try { throw new InvalidOperationException( message: $"Длина очереди доставки сообщений достигла предела предупреждения '{__PostingQueueLengthWarning:d}' и составляет '{postingQueueLength:d}'.{Environment.NewLine}Слишком большая очередь доставки сообщений свидетельствует о некорректной работе компонентов, выполняющих доставку сообщений, либо о слишком большом потоке сообщений.{Environment.NewLine}Данное событие не прерывает работу, если оно успешно записано в системый журнал событий."); } catch (Exception firstException) { WindowsEventLogUtilities.WriteFaultToEventLog(fault: firstException, failFastOnError: true, faultFormattingOptions: ExceptionInfoFormattingOptions.Full); } } #else // TODO_HIGH: Implement logging (as for TRG_NETFRAMEWORK). // // ... #endif // Уведомление воркеров (рабочих элементов, обрабатывающих доставку сообщений). // var postingWorkers = ReadDA(ref _postingWorkers); for (var i = 0; i < postingWorkers.Length; i++) { ILocalPostingWorker postingWorker = ReadDA(ref postingWorkers[i]); postingWorker.BreakLoopIdle(); #if TRG_NETFRAMEWORK if (!postingWorker.IsLoopAlive) { if (!runControl.HasStopRequested) { try { throw new InvalidOperationException( message: $"Один из рабочих элементов (#{(i + 1):d} из {postingWorkers.Length:d}), выполняющий доставку сообщений, находится в нерабочем состоянии.{Environment.NewLine}Данное событие не прерывает работу, если оно успешно записано в системый журнал событий."); } catch (Exception firstException) { WindowsEventLogUtilities.WriteFaultToEventLog(fault: firstException, failFastOnError: true, faultFormattingOptions: ExceptionInfoFormattingOptions.Full); } } } // TimeSpan?currentPostingDuration; if ((currentPostingDuration = postingWorker.CurrentlyPostingDuration) >= __PostingOperationDurationWarning) { var currentPostingSubscription = postingWorker.CurrentlyPostingSubscription; try { throw new InvalidOperationException( message: $"Время выполнения операции доставки, выполняемой одним из рабочих элементов (#{(i + 1):d} из {postingWorkers.Length:d}), достигло предела предупреждения '{__PostingOperationDurationWarning.ToString("c")}' и составляет '{currentPostingDuration.Value.ToString("c")}'.{Environment.NewLine}\tПодписка, согласно которой выполняется доставка:{currentPostingSubscription.FmtStr().GNLI2()}{Environment.NewLine}Данное событие не прерывает работу, если оно успешно записано в системый журнал событий.{Environment.NewLine}Указанное событие сообщает о том, что один из рабочих элементов уже слишком долго выполняет операцию доставки, что не является нормальным."); } catch (Exception firstException) { WindowsEventLogUtilities.WriteFaultToEventLog(fault: firstException, failFastOnError: true, faultFormattingOptions: ExceptionInfoFormattingOptions.Full); } } #else // TODO_HIGH: Implement logging (as for TRG_NETFRAMEWORK). // // ... #endif } } catch (Exception exception) { postingQueueEntry?.Dispose(exception); throw; } } else { postingToken = new LocalPostingToken(message: msg, disposeMessageAtEndOfPosting: disposeMessageAtEndOfPosting); if (disposeMessageAtEndOfPosting) { msg.Dispose(); } } return(postingToken); }