// TODO: Put strings into the resources. // bool P_Signal(ITriggerSignalProperties signalProps, Func <ITriggerSignalProperties, TriggerSignalState, TriggerSignalState> condition) { signalProps.EnsureNotNull(nameof(signalProps)); signalProps.Trigger.ArgProp($"{nameof(signalProps)}.{nameof(signalProps.Trigger)}").EnsureIs(operand: this); condition.EnsureNotNull(nameof(condition)); // TriggerSignalEventArgs signalEventArgs = default; for (; P_CanSignal();) { var inState = itrlck.Get(ref _signalState); var outState = condition(arg1: signalProps, arg2: inState); if (ReferenceEquals(inState, outState)) { return(false); } else if (outState.SignalCounter < (inState?.SignalCounter ?? 0L)) { throw new EonException(message: $"Не выполняется условие '{nameof(inState)}.{nameof(inState.SignalCounter)} <= {nameof(outState)}.{nameof(outState.SignalCounter)}.'"); } else if (itrlck.UpdateBool(location: ref _signalState, value: outState, comparand: inState)) { if (P_CanSignal() && (inState?.SignalCounter ?? 0L) != outState.SignalCounter) { itrlck.SetNull(location: ref _nextSignalAwaitable)?.TrySetResult(result: signalEventArgs = signalEventArgs ?? new TriggerSignalEventArgs(signalProps: signalProps)); return(true); } else { return(false); } } } return(false); }
// TODO: Put strings into the resources. // void P_OnTriggerSignalReceived(ITriggerSignalProperties signalProps) { var unhandledExceptionObserver = TryReadDA(ref _unhandledExceptionObserver); if (!IsDisposeRequested) { try { Exception signalCaughtException = default; try { OnSignal(signalProps: signalProps); } catch (Exception exception) { signalCaughtException = new EonException(message: $"Ошибка обработчика сигнала триггера по подписке.{Environment.NewLine}\tСигнал:{signalProps.FmtStr().GNLI2()}", innerException: exception); } try { P_SubscribeToNextSignal(); } catch (Exception exception) { if (signalCaughtException is null) { throw; } else { throw new AggregateException(signalCaughtException, exception); } } } catch (Exception exception) { if (!unhandledExceptionObserver.ObserveException(exception: exception, component: signalProps)) { throw; } } } }
protected override void SignalCondition(ITriggerSignalProperties signalProps, TriggerSignalState inState, out TriggerSignalState outState) { signalProps.EnsureNotNull(nameof(signalProps)); // if ((inState is null) || inState.SignalCounter == 0 || signalProps.Timestamp.Subtract(inState.LastSignalTimestamp) > _signalFrequencyLimit) { base.SignalCondition(signalProps: signalProps, inState: inState, outState: out outState); }
TriggerSignalState P_AtMostOneSignalCondition(ITriggerSignalProperties signalProps, TriggerSignalState inState) { if ((inState?.SignalCounter ?? 0L) == 0L) { return(P_DefaultSignalCondition(signalProps: signalProps, inState: inState)); } else { return(inState); } }
public TriggerSignalProperties(ITrigger trigger, ITriggerSignalProperties source, ArgumentPlaceholder <DateTimeOffset> timestamp = default) { trigger.EnsureNotNull(nameof(trigger)); source.EnsureNotNull(nameof(source)); // _trigger = trigger; _source = source; _timestamp = timestamp.Substitute(value: source.Timestamp); _correlationId = source.CorrelationId; _explicitlyDefinedProps = timestamp.HasExplicitValue ? ExplicitlyDefinedProps.Timestamp : ExplicitlyDefinedProps.None; }
public TriggerSignalProperties(ITrigger trigger, ArgumentPlaceholder <DateTimeOffset> timestamp = default, ArgumentPlaceholder <XFullCorrelationId> correlationId = default) { trigger.EnsureNotNull(nameof(trigger)); if (correlationId.HasExplicitValue && correlationId.ExplicitValue.IsEmpty) { throw new ArgumentException(message: "Cannot be empty.", paramName: nameof(correlationId)); } // _trigger = trigger; _source = null; _timestamp = timestamp.Substitute(value: DateTimeOffset.Now); _correlationId = correlationId.Substitute(value: default);
// TODO: Put strings into the resources. // void P_ResetTrigger_OnSignal(ITriggerSignalProperties signalProps, IDisposable subscription) { signalProps.EnsureNotNull(nameof(signalProps)); subscription.EnsureNotNull(nameof(subscription)); // var resetTrigger = TryReadDA(ref _resetTrigger); var resetTriggerSubscription = TryReadDA(ref _resetTriggerSignalSubscription, considerDisposeRequest: true); if (ReferenceEquals(resetTrigger, signalProps.Trigger) && ReferenceEquals(resetTriggerSubscription, subscription)) { try { if (signalProps.Trigger.IsDisabled) { return; } } catch (ObjectDisposedException) { return; } if (IsActive) { TaskUtilities.RunOnDefaultScheduler(factory: () => resetComponentAsync(locTriggerSignalProps: signalProps)); } } // async Task resetComponentAsync(ITriggerSignalProperties locTriggerSignalProps) { try { using (var localCtx = ContextUtilities.Create(fullCorrelationId: signalProps.CorrelationId)) await P_ResetComponentAsync(triggerSignalProps : locTriggerSignalProps, doFailureResponse : true, ctx : localCtx).ConfigureAwait(false); } catch (Exception exception) { if (!((exception is ObjectDisposedException && IsDisposeRequested) || exception.HasSingleBaseExceptionOf <OperationCanceledException>() || exception.IsObserved())) { #if !DO_NOT_USE_EON_LOGGING_API this .IssueError( message: $"Сбой установки (замены) компонента, инициированной триггером.{Environment.NewLine}\tСобытие-инициатор:{locTriggerSignalProps.FmtStr().GNLI2()}", error: exception, includeErrorInIssueFaultException: true, severityLevel: exception.GetMostHighSeverityLevel(baseLevel: SeverityLevel.Medium)); #endif } } } }
public static ITriggerSignalProperties GetOriginator(this ITriggerSignalProperties signalProps) { signalProps.EnsureNotNull(nameof(signalProps)); // var source = signalProps; for (; ;) { var nextSource = source.Source; if (nextSource is null) { return(source); } else { source = nextSource; } } }
protected virtual void SignalCondition(ITriggerSignalProperties signalProps, TriggerSignalState inState, out TriggerSignalState outState) { signalProps.EnsureNotNull(nameof(signalProps)); // if (inState is null) { outState = new TriggerSignalState(signalCounter: 1L, lastSignalTimestamp: signalProps.Timestamp); } else { switch (inState.SignalCounter) { case long.MaxValue: outState = inState; break; default: outState = new TriggerSignalState(signalCounter: inState.SignalCounter + 1L, lastSignalTimestamp: signalProps.Timestamp); break; } } }
public TriggerSignalEventArgs(ITriggerSignalProperties signalProps) { signalProps.EnsureNotNull(nameof(signalProps)); // _signalProperties = signalProps; }
// TODO: Put strings into the resources. // Task <IXAppScopeInstance> P_ResetComponentAsync(Func <IContext, bool> breakCondition = default, ITriggerSignalProperties triggerSignalProps = default, bool doFailureResponse = default, IContext ctx = default) { try { if (breakCondition is null) { breakCondition = (locContext) => { locContext.ThrowIfCancellationRequested(); return(!IsActive || HasDeactivationRequested); } } ; // var startTimestamp = StopwatchUtilities.GetTimestampAsTimeSpan(); IContext locCtx = default; try { var resetNumber = Interlocked.Increment(ref _resetCounter); var failureResponseDlg = ReadIA(ref _resetFailureResponseDelegate, isNotRequired: true, locationName: nameof(_resetFailureResponseDelegate)); var state = new P_ResetState(); locCtx = CreateScopedContext(outerCtx: ctx, localTag: state); var logMessagePrologue = $"{(resetNumber == 0 ? "Установка компонента." : $"Замена (переустановка) компонента. Порядковый номер замены: {resetNumber:d}.")} ИД корреляции: {locCtx.FullCorrelationId}.{(triggerSignalProps is null ? string.Empty : $"{Environment.NewLine}\tСобытие-инициатор:{triggerSignalProps.FmtStr().GNLI2()}")}"; if (locCtx.IsCancellationRequested()) { return(Task.FromCanceled <IXAppScopeInstance>(cancellationToken: locCtx.Ct())); } var resetTask = TaskUtilities.RunOnDefaultScheduler(factory: async() => await doResetAsync(locCtx: locCtx).ConfigureAwait(false)); // Вывод результатов ресета в лог. // #if !DO_NOT_USE_EON_LOGGING_API resetTask .ContinueWith( continuationAction: locTask => { var locDuration = StopwatchUtilities.GetTimestampAsTimeSpan().Subtract(ts: startTimestamp); if (locTask.IsFaulted) { this .IssueError( messagePrologue: logMessagePrologue, message: $"Длительность:{locDuration.ToString("c").FmtStr().GNLI()}{Environment.NewLine}Сбой.", error: locTask.Exception, includeErrorInIssueFaultException: true, severityLevel: locTask.Exception.GetMostHighSeverityLevel(baseLevel: SeverityLevel.Medium)); locTask.Exception.MarkAsObserved(); } else if (locTask.IsCanceled) { this .IssueWarning( messagePrologue: logMessagePrologue, message: $"Длительность:{locDuration.ToString("c").FmtStr().GNLI()}{Environment.NewLine}Отменено или прервано.", severityLevel: SeverityLevel.Medium); } else { this .IssueInformation( messagePrologue: logMessagePrologue, message: $"Длительность:{locDuration.ToString("c").FmtStr().GNLI()}{Environment.NewLine}Успешно выполнено.{Environment.NewLine}\tНовый экземпляр компонента:{locTask.Result.FmtStr().GNLI2()}", severityLevel: SeverityLevel.Medium); } }, continuationOptions: TaskContinuationOptions.ExecuteSynchronously); #endif // Обработка сбоя ресета. // Task failureResponseTask; if (doFailureResponse && !(failureResponseDlg is null)) { failureResponseTask = resetTask .ContinueWith( continuationFunction: locTask => { if (!(state.PreviousComponent is null)) { // Корректирующие действие сбоя ресета выполняется только в случае именно замены компонента. // return (doFailureCorrectiveAsync( locFailure: locTask.Exception, responseDlg: failureResponseDlg, locCtx: locCtx, logMessagePrologue: logMessagePrologue)); } else { return(TaskUtilities.FromCanceled()); } }, continuationOptions: TaskContinuationOptions.PreferFairness | TaskContinuationOptions.OnlyOnFaulted) .Unwrap(); // Вывод результатов обработки сбоя в лог. // #if !DO_NOT_USE_EON_LOGGING_API failureResponseTask .ContinueWith( continuationAction: locTask => { if (locTask.IsFaulted) { this .IssueError( messagePrologue: logMessagePrologue, message: $"Корректирующее действие при сбое замены (переустановки) компонента.{Environment.NewLine}Сбой корректирующего действия.", error: locTask.Exception, includeErrorInIssueFaultException: true, severityLevel: locTask.Exception.GetMostHighSeverityLevel(baseLevel: SeverityLevel.High)); } else { this .IssueInformation( messagePrologue: logMessagePrologue, message: $"Корректирующее действие при сбое замены (переустановки) компонента.{Environment.NewLine}Корректирующее действие успешно выполнено.", severityLevel: SeverityLevel.Medium); } }, continuationOptions: TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnCanceled); #endif }
public bool SignalAtMostOne(ITriggerSignalProperties signalProps) => P_Signal(signalProps: signalProps, condition: P_AtMostOneSignalCondition);
TriggerSignalState P_DefaultSignalCondition(ITriggerSignalProperties signalProps, TriggerSignalState inState) { SignalCondition(signalProps: signalProps, inState: inState, outState: out var outState); return(outState); }
public bool Signal(ITriggerSignalProperties signalProps) => P_Signal(signalProps: signalProps, condition: P_DefaultSignalCondition);
protected abstract void OnSignal(ITriggerSignalProperties signalProps);
protected override void OnSignal(ITriggerSignalProperties signalProps) => TryReadDA(ref _onSignal, considerDisposeRequest: true)?.Invoke(arg1: signalProps, arg2: this);