Esempio n. 1
0
 internal P_NewSubscriptionRegistrationState(ILocalSubscription subscription)
 {
     subscription.EnsureNotNull(nameof(subscription));
     //
     Subscription       = subscription;
     SubscribeTaskProxy = new TaskCompletionSource <ILocalSubscription>(TaskContinuationOptions.None);
 }
Esempio n. 2
0
        // TODO: Put strings into the resources.
        //
        async Task ILocalSubscriber.OnSubscriptionDeactivationAsync(ILocalSubscription subscription, IContext ctx)
        {
            subscription.EnsureNotNull(nameof(subscription));
            //
            if (ReferenceEquals(subscription, ReadDA(ref _activatedSubscription)))
            {
                var lck         = ReadDA(ref _processMessagePostLock);
                var lckAcquired = false;
                try {
                    lckAcquired = await lck.WaitAsync(millisecondsTimeout : TaskUtilities.DefaultAsyncTimeoutMilliseconds, cancellationToken : ctx.Ct()).ConfigureAwait(false);

                    if (!lckAcquired)
                    {
                        throw new LockAcquisitionFailException(reason: LockAcquisitionFailReason.TimeoutElapsed);
                    }
                    //
                    await OnSubscriptionDeactivationAsync(subscription : subscription, ctx : ctx).ConfigureAwait(false);

                    Interlocked.CompareExchange(ref _activatedSubscription, null, comparand: subscription);
                }
                finally {
                    if (lckAcquired)
                    {
                        try { lck.Release(); }
                        catch (ObjectDisposedException) { }
                    }
                }
            }
            else
            {
                throw
                    new InvalidOperationException(
                        $"Недопустимый вызов операции деактивации подписки для данного подписчика. Указанная подписка не была активирована для подписчика.{Environment.NewLine}\tПодписка:{subscription.FmtStr().GNLI2()}{Environment.NewLine}\tПодписчик:{this.FmtStr().GNLI2()}");
            }
        }
Esempio n. 3
0
 static async Task P_DoSingleMessagePostingAsync(LocalPostingToken token, ILocalSubscription subscription, CancellationToken ct)
 {
     token.EnsureNotNull(nameof(token));
     subscription.EnsureNotNull(nameof(subscription));
     //
     if (subscription.IsActive)
     {
         ILocalSubscriber subscriber;
         try {
             subscriber = subscription.Subscriber;
         }
         catch (ObjectDisposedException) {
             if (subscription.IsActive)
             {
                 throw;
             }
             else
             {
                 return;
             }
         }
         //
         using (var context = ContextUtilities.Create(ct: ct))
             await subscriber.ProcessMessagePostAsync(subscription : subscription, message : token.Message, ctx : context).ConfigureAwait(false);
         //
         token.NotifySubscriptionPosted();
     }
 }
Esempio n. 4
0
 public LocalPublicationFilterEventArgs(ILocalSubscription subscription, ILocalMessage <TPayload> message)
 {
     subscription.EnsureNotNull(nameof(subscription));
     message.EnsureNotNull(nameof(message));
     //
     _subscription = subscription;
     _message      = message;
 }
Esempio n. 5
0
 public LocalPublicationFilterState(ILocalMessage message, ILocalSubscription subscription)
 {
     message.EnsureNotNull(nameof(message));
     subscription.EnsureNotNull(nameof(subscription));
     //
     _message      = message;
     _subscription = subscription;
 }
Esempio n. 6
0
        protected override async Task OnSubscriptionDeactivationAsync(ILocalSubscription subscription, IContext ctx = default)
        {
            var userDelegate = ReadDA(ref _onSubscriptionDeactivationUserDelegate);

            if (!(userDelegate is null))
            {
                await userDelegate(subscription : subscription, ctx : ctx).ConfigureAwait(false);
            }
        }
Esempio n. 7
0
 internal P_LoopSingleItemPostingState(LocalPostingWorker worker, ILocalSubscription subscription)
 {
     worker.EnsureNotNull(nameof(worker));
     subscription.EnsureNotNull(nameof(subscription));
     //
     _worker            = worker;
     _subscription      = subscription;
     _startTimestamp    = -1L;
     _completeTimestamp = -1L;
 }
Esempio n. 8
0
        // TODO: Put strings into the resources.
        //
        async Task ILocalSubscriber.OnSubscriptionActivationAsync(ILocalSubscription subscription, IContext ctx)
        {
            subscription.EnsureNotNull(nameof(subscription));
            //
            if (!ReferenceEquals(objA: subscription.Subscriber, objB: this))
            {
                throw
                    new ArgumentOutOfRangeException(
                        paramName: nameof(subscription),
                        message: $"Указанная подписка не относится к данному подписчику.{Environment.NewLine}\tПодписка:{subscription.FmtStr().GNLI2()}{Environment.NewLine}\tПодписчик:{this.FmtStr().GNLI2()}");
            }
            else if (!ReferenceEquals(ReadDA(ref _activatedSubscription), subscription))
            {
                ILocalSubscription original;
                var lck         = ReadDA(ref _processMessagePostLock);
                var lckAcquired = false;
                try {
                    lckAcquired = await lck.WaitAsync(millisecondsTimeout : TaskUtilities.DefaultAsyncTimeoutMilliseconds, cancellationToken : ctx.Ct()).ConfigureAwait(false);

                    if (!lckAcquired)
                    {
                        throw new LockAcquisitionFailException(reason: LockAcquisitionFailReason.TimeoutElapsed);
                    }
                    //
                    if (!((original = WriteDA(ref _activatedSubscription, subscription, null)) == null || ReferenceEquals(original, subscription)))
                    {
                        throw
                            new InvalidOperationException(
                                $"Невозможно активировать еще одну подписку для данного подписчика. Подписчик не поддерживает работу с несколькими подписками.{Environment.NewLine}\tПодписка:{Environment.NewLine}{subscription.FmtStr().GI2()}{Environment.NewLine}\tПодписчик:{Environment.NewLine}{this.FmtStr().GI2()}");
                    }
                    else if (original == null)
                    {
                        try {
                            await OnSubscriptionActivationAsync(subscription : subscription, ctx : ctx).ConfigureAwait(false);
                        }
                        catch {
                            Interlocked.CompareExchange(ref _activatedSubscription, original, subscription);
                            throw;
                        }
                    }
                }
                finally {
                    if (lckAcquired)
                    {
                        try { lck.Release(); }
                        catch (ObjectDisposedException) { }
                    }
                }
            }
        }
 protected override void Dispose(bool explicitDispose)
 {
     if (explicitDispose)
     {
         _appStartedSubscription?.Dispose();
         _lastComponentActivation?.Dispose();
     }
     _appStartedSubscription  = null;
     _retryOptions            = null;
     _lastComponentActivation = null;
     _activateControlFactory  = null;
     //
     base.Dispose(explicitDispose);
 }
Esempio n. 10
0
 public virtual bool Equals(ILocalSubscription other)
 {
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     else if (other is null)
     {
         return(false);
     }
     else
     {
         return(__PublisherEqComparer.Equals(x: Publisher, y: other.Publisher) && __SubscriberEqComparer.Equals(x: Subscriber, y: other.Subscriber));
     }
 }
        // TODO: Put strings into the resources.
        //
        Task P_HandleAppStartedNotificationAsync(ILocalSubscription subscription, ILocalMessage <IXAppStartedEventArgs> message, IContext ctx)
        {
            try {
                subscription.EnsureNotNull(nameof(subscription));
                message.EnsureNotNull(nameof(message));
                ctx.EnsureNotNull(nameof(ctx));
                //
                if (ctx.IsCancellationRequested())
                {
                    return(Task.FromCanceled(cancellationToken: ctx.Ct()));
                }
                else if (HasDeactivationRequested || !IsActive || !subscription.IsActive || !ReferenceEquals(subscription, TryReadDA(ref _appStartedSubscription)))
                {
                    return(Task.CompletedTask);
                }
                else
                {
                    var retryOptions = TryReadDA(ref _retryOptions, considerDisposeRequest: true);
                    if (retryOptions is null)
                    {
                        if (!IsDisposeRequested)
                        {
                            EnsureInitialized();
                        }
                        return(TaskUtilities.FromCanceled());
                    }
                    else
                    {
#if !DO_NOT_USE_EON_LOGGING_API
                        var logMessagePrologue = $"Отложенная активация. ИД корреляции: {ctx.FullCorrelationId}.";
                        this
                        .IssueInformation(
                            messagePrologue: logMessagePrologue,
                            message: "Получено уведомление о запуске приложения. Начало активации.",
                            severityLevel: SeverityLevel.Medium);
#endif
                        P_StartComponentActivationAttempt(retryOptions: retryOptions, rethrowException: false, retryAttemptIndex: -1, correlationId: ctx.FullCorrelationId, ct: message.Payload.App.AppShutdownToken);
                        return(Task.CompletedTask);
                    }
                }
            }
            catch (Exception exception) {
                return(Task.FromException(exception));
            }
        }
Esempio n. 12
0
 public virtual Task <ILocalSubscription> SubscribeAsync(ILocalSubscription subscription)
 => InnerPublisher.SubscribeAsync(subscription: subscription);
Esempio n. 13
0
 public bool TryGetNextPostingSubscription(out LocalPostingToken postingToken, out ILocalSubscription postingSubscription)
 {
     if (TryReadDA(ref _postingSubscriptionsSpinLock, considerDisposeRequest: true, result: out var subscriptionsSpinLock) &&
         TryReadDA(ref _postingSubscriptions, considerDisposeRequest: true, result: out var subscriptions) &&
         TryReadDA(ref _postingToken, considerDisposeRequest: true, result: out var locPostingToken))
     {
         //
         var locPostingSubscription =
             subscriptionsSpinLock
             .Invoke(
                 () => {
             if (subscriptions.Count < 1)
             {
                 return(null);
             }
             else
             {
                 return(subscriptions.RemoveItemAt(index: 0));
             }
         });
         postingSubscription = locPostingSubscription;
         postingToken        = locPostingSubscription == null ? null : locPostingToken;
         return(locPostingSubscription != null);
     }
Esempio n. 14
0
 protected abstract Task OnSubscriptionActivationAsync(ILocalSubscription subscription, IContext ctx = default);
Esempio n. 15
0
 // TODO: Put strings into the resources.
 //
 public Task <ILocalSubscription> SubscribeAsync(ILocalSubscription subscription)
 {
     try {
         subscription.EnsureNotNull(nameof(subscription));
         if (!ReferenceEquals(subscription.Publisher, this))
         {
             throw
                 new ArgumentOutOfRangeException(
                     paramName: nameof(subscription),
                     message: $"Subscription is not associated with this publisher.{Environment.NewLine}\tSubscription:{subscription.FmtStr().GNLI2()}{Environment.NewLine}\tPublisher:{this.FmtStr().GNLI2()}");
         }
         //
         var spinLock = ReadDA(ref _subscriptionsSpinLock);
         var subscriptionsDictionary          = ReadDA(ref _subscriptionsDictionary);
         var subscriptionsList                = ReadDA(ref _subscriptionsList);
         var existingSubscriptionRegistration = default(P_NewSubscriptionRegistrationState);
         //
         if (!spinLock.Invoke(() => subscriptionsDictionary.TryGetValue(subscription, out existingSubscriptionRegistration)))
         {
             var newSubscriptionRegistration = default(P_NewSubscriptionRegistrationState);
             try {
                 newSubscriptionRegistration = new P_NewSubscriptionRegistrationState(subscription);
                 spinLock
                 .Invoke(
                     () => {
                     EnsureNotDisposeState();
                     //
                     if (subscriptionsDictionary.ContainsKey(subscription))
                     {
                         existingSubscriptionRegistration = subscriptionsDictionary[subscription];
                     }
                     else
                     {
                         subscriptionsDictionary.Add(subscription, newSubscriptionRegistration);
                         existingSubscriptionRegistration = newSubscriptionRegistration;
                         subscriptionsList.Add(newSubscriptionRegistration.Subscription);
                     }
                 });
                 if (existingSubscriptionRegistration == newSubscriptionRegistration)
                 {
                     subscription
                     .ActivateAsync()
                     .ContinueWith(
                         locActivateTask => {
                         if (locActivateTask.IsCanceled)
                         {
                             newSubscriptionRegistration.SubscribeTaskProxy.TrySetCanceled();
                         }
                         else if (locActivateTask.IsFaulted)
                         {
                             if (!newSubscriptionRegistration.SubscribeTaskProxy.TrySetException(locActivateTask.Exception))
                             {
                                 throw new AggregateException(locActivateTask.Exception);
                             }
                         }
                         else
                         {
                             newSubscriptionRegistration.SubscribeTaskProxy.TrySetResult(newSubscriptionRegistration.Subscription);
                         }
                     },
                         TaskContinuationOptions.ExecuteSynchronously);
                 }
             }
             catch (Exception firstException) {
                 newSubscriptionRegistration?.SubscribeTaskProxy.TrySetException(firstException);
                 throw;
             }
             finally {
                 if (newSubscriptionRegistration != existingSubscriptionRegistration)
                 {
                     newSubscriptionRegistration?.SubscribeTaskProxy.TrySetCanceled();
                 }
             }
         }
         //
         return(existingSubscriptionRegistration.SubscribeTaskProxy.Task);
     }
     catch (Exception firstException) {
         return(TaskUtilities.FromError <ILocalSubscription>(firstException));
     }
 }
Esempio n. 16
0
        protected sealed override async Task ProcessMessageAsync(ILocalSubscription subscription, ILocalMessage <TPayload> message, IContext ctx = default)
        {
            var userDelegate = ReadDA(ref _processMessageUserDelegate);

            await userDelegate(subscription : subscription, message : message, ctx : ctx).ConfigureAwait(false);
        }