コード例 #1
0
        // 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);
            }
        }
コード例 #2
0
 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;
 }
コード例 #3
0
 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;
 }
コード例 #4
0
        // 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);
                }
            }
        }
コード例 #5
0
 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);
コード例 #6
0
        // 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;
                }
            }
        }
コード例 #7
0
		// 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;
		}
コード例 #8
0
 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);
コード例 #9
0
 public RunControlEventArgs(IRunControl runControl)
 {
     runControl.EnsureNotNull(nameof(runControl));
     //
     RunControl = runControl;
 }
コード例 #10
0
        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);
        }