Esempio n. 1
0
        /// <summary>
        /// Perform event subscription (Subscribe), always asynchronous.
        /// </summary>
        public bool Subscribe <TType>(SuperPoolClient subscriber,
                                      EventSubscriptionRequest request, out TType resultValue)
            where TType : class
        {
            SuperPoolProxyCall call;
            bool result = Call <TType>(subscriber, out resultValue, out call);

            call.SubscriptionRequest = request;

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Perform an event subscription.
        /// All subscribes are expected to be asynchronous,
        /// and executed agains the actual pool only.
        /// </summary>
        public TType Subscribe <TType>(EventSubscriptionRequest subscription)
            where TType : class
        {
            Matrix.Framework.SuperPool.Core.SuperPool pool = _superPool;
            if (pool == null)
            {
                return(null);
            }

            TType result;

            if (pool.Subscribe <TType>(this, subscription, out result))
            {
                return(result);
            }

            return(null);
        }
Esempio n. 3
0
        public TType Subscribe <TType>(EventSubscriptionRequest subscription) where TType : class
        {
            SuperPool superPool = this._superPool;

            if (superPool == null)
            {
                return(default(TType));
            }
            TType resultValue;

            if (superPool.Subscribe <TType>(this, subscription, out resultValue))
            {
                return(resultValue);
            }
            else
            {
                return(default(TType));
            }
        }
Esempio n. 4
0
        void ISuperPoolIntercom.ProcessSubscriptionUpdate(EventSubscriptionRequest subscriptionRequest)
        {
            // Filter request, since it may not be related at all to this super pool.
            bool clientFound = false;
            ReadOnlyCollection <ClientId> sources = subscriptionRequest.EventsSources;

            if (sources == null)
            {// Null value indicates a subscirption to all possible sources.
                clientFound = true;
            }
            else
            {
                foreach (ClientId id in sources)
                {
                    if (_clients.ContainsKey(id))
                    {
                        clientFound = true;
                        break;
                    }
                }
            }

            // Check the sources and the SenderId, before dumping event.
            if (clientFound == false && subscriptionRequest.SenderId.IsLocalClientId == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Info("Subscription request received [" + subscriptionRequest.ToString() + "], ignored since not related.");
#endif
                return;
            }
            else
            {
#if Matrix_Diagnostics
                InstanceMonitor.Info("Subscription request received [" + subscriptionRequest.ToString() + "] and processing...");
#endif
            }

            EventSubscriptionInfo methodSubscription = null;
            if (_eventSubscriptions.TryGetValue(subscriptionRequest.ExtendedEventName, out methodSubscription) == false)
            {
                lock (_syncRoot)
                {
                    if (_eventSubscriptions.TryGetValue(subscriptionRequest.ExtendedEventName, out methodSubscription) == false)
                    {// Add a new method subscription info.
                        methodSubscription = new EventSubscriptionInfo(subscriptionRequest.ExtendedEventName);
                        _eventSubscriptions.Add(subscriptionRequest.ExtendedEventName, methodSubscription);
                    }
                }
            }

            if (methodSubscription == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find method subscription, subscription failed.");
#endif
                return;
            }

            // Apply the requests locally.
            methodSubscription.SubscriptionUpdate(subscriptionRequest);
        }
Esempio n. 5
0
        /// <summary>
        /// Handle event subscription (Proxy.Event.Subscribe)
        /// </summary>
        protected override void ProcessReceiveEventSubscription(int methodId, Delegate delegateInstance, bool isAdd)
        {
            SuperPoolProxyCall pendingCall = null;

            if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out pendingCall) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding thread proxy call information.");
#endif
                return;
            }

            EventSubscriptionRequest subscriptionRequest = pendingCall.SubscriptionRequest;
            if (subscriptionRequest == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding subscription requests, event subscription failed.");
#endif
                return;
            }

            if (pendingCall.Sender == null || pendingCall.Sender.Id == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to establish subscription sender information, subscription failed.");
#endif
                return;
            }

            if (delegateInstance.Target != pendingCall.Sender.Source)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Only a message super pool client source can subscribe to events.");
#endif
                return;
            }

            ProxyTypeBuilder builder = ProxyTypeBuilder;
            if (builder == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find proxy type builder, event subscription failed.");
#endif
                return;
            }

            GeneratedMethodInfo generatedMethodInfo = builder.GetMethodInfoById(methodId);
            if (generatedMethodInfo == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find method [id, " + methodId + "] info, event subscription failed.");
#endif
                return;
            }

            if (string.IsNullOrEmpty(generatedMethodInfo.EventName))
            {
                generatedMethodInfo.EventName = GeneralHelper.GetEventExtendedNameByMethod(generatedMethodInfo.GetMethodInfo(), false, true);
            }

            // generatedMethodInfo.GetMethodInfo() >> I2.add_AEVent
            string     extendedEventName  = generatedMethodInfo.EventName;
            MethodInfo eventAddMethodInfo = generatedMethodInfo.GetMethodInfo();

            // *IMPORTANT* the Call<> will cause the currently used pendingCall to be repopulated with information,
            // so we ned to extract the *sender id* BEFORE calling the actual Call(), since it will change the
            // pendingCall instance immediately.
            subscriptionRequest.SenderId          = pendingCall.Sender.Id;
            subscriptionRequest.ExtendedEventName = extendedEventName;
            subscriptionRequest.IsAdd             = isAdd;
            //subscriptionRequest.EventAddMethodInfo = eventAddMethodInfo;
            subscriptionRequest.DelegateInstanceMethodInfo = delegateInstance.Method;

            // Process locally.
            ((ISuperPoolIntercom)this).ProcessSubscriptionUpdate(subscriptionRequest);

            SuperPoolClient mainClient = IntercomClient;
            if (mainClient == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Failed to obtain super pool main intercom client, so new client handling has failed.");
#endif
            }
            else
            {
                // Notify other connected super pools of this subcription,
                // since the subscribee(s) may be attached on them.
                // *pendingCall swap done here, make sure to not use it on or after this line*
                mainClient.CallAll <ISuperPoolIntercom>().ProcessSubscriptionUpdate(subscriptionRequest);
            }
        }