/// <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); }
/// <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); }
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)); } }
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); }
/// <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); } }