예제 #1
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //// [Optional] Assign the default tracer, to provide system wide tracing functionality.
            //SystemMonitor.AssignTracer(new Tracer());
            //this.tracerControl1.Tracer = SystemMonitor.Tracer;

            // Create the underlying (server) message bus and put the pool on it.
            ServerMessageBus messageBus = new ServerMessageBus("Server", null, null);

            _pool = new Matrix.Framework.SuperPool.Core.SuperPool(messageBus);

            // Create the client that will server as a connection between this
            // class and the super pool and add the client to the pool.
            _poolClient = new SuperPoolClient("Server", this);
            _pool.AddClient(_poolClient);

            // Finally subscribe to the event of having a client added to the bus/pool.
            _pool.MessageBus.ClientAddedEvent += new MessageBus.Core.MessageBusClientUpdateDelegate(MessageBus_ClientAddedEvent);
            messageBus.ClientRemovedEvent     += (bus, id, remove) =>
            {
                this.Invoke(new GeneralHelper.GenericDelegate <string>(Report),
                            "Client removed " + id.ToString());
            };
        }
예제 #2
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Text += " - " + this.ClientName;

            // The steps here are exactly the same, as in server side, only difference is the ClientMessageBus
            // instead of ServerMessageBus. Since this is the only difference, all the remaining source code
            // is completely independent of whether its a server or a client side.

            //// Assign the default tracer, to provide system wide tracing functionality.
            //SystemMonitor.AssignTracer(new Tracer());
            //this.tracerControl1.Tracer = SystemMonitor.Tracer;

            IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, ServerMessageBus.DefaultPort);

            // Create the underlying (client) message bus, that takes care of transporting the
            // actual communication messages; the message bus TCP communication is created
            // at default port, at localhost.
            ClientMessageBus messageBus = new ClientMessageBus(endPoint, this.ClientName, null);

            // Initialize the super pool with this message bus.
            _pool = new Matrix.Framework.SuperPool.Core.SuperPool(messageBus);

            // Create the client that will server as a connection between this
            // class and the super pool and add the client to the pool.
            _poolClient = new SuperPoolClient("Client." + this.ClientName, this);
            _pool.AddClient(_poolClient);

            // Use this to assign a specific execution strategy to a given client.
            // _poolClient.SetupExecutionStrategy(new FrameworkThreadPoolExecutionStrategy());
        }
예제 #3
0
        /// <summary>
        /// Creates a new client, assigns it with a custom execution strategy and adds it to the super pool.
        /// </summary>
        /// <param name="superPool"></param>
        public void Demonstrate(Matrix.Framework.SuperPool.Core.SuperPool superPool)
        {
            SuperPoolClient client = new SuperPoolClient("Client", this);
            client.SetupExecutionStrategy(new CustomExecutionStrategy());

            superPool.AddClient(client);
        }
예제 #4
0
        public void AcceptResponse(SuperPoolClient client, object result, Exception exception)
        {
            Response = result;

            if (AsyncResultDelegate != null)
            {
                try
                {
                    AsyncResultDelegate.Invoke(client, new AsyncResultParams()
                    {
                        Result = result, State = AsyncResultState, Exception = exception
                    });
                }
                catch (Exception ex)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError(string.Format("AcceptReposnse invoke of client [{0}] has caused an exception", client.Name), ex);
#endif
                }
            }
            else
            {// Assign the parameter only in sync calls, since async already consumed it trough async delegate.
                Exception = exception;
            }

            ManualResetEvent eventInstance = Event;
            if (eventInstance != null)
            {
                eventInstance.Set();
            }
        }
예제 #5
0
        /// <summary>
        /// Creates a new client, assigns it with a custom execution strategy and adds it to the super pool.
        /// </summary>
        /// <param name="superPool"></param>
        public void Demonstrate(Matrix.Framework.SuperPool.Core.SuperPool superPool)
        {
            SuperPoolClient client = new SuperPoolClient("Client", this);

            client.SetupExecutionStrategy(new CustomExecutionStrategy());

            superPool.AddClient(client);
        }
예제 #6
0
        /// <summary>
        /// Constructor.
        /// </summary>
        internal CallTestImplementor()
        {
            _implementor1 = new InterfaceImplementor("Implementor1");
            _implementor2 = new InterfaceImplementor("Implementor2");

            Client1 = new SuperPoolClient("client1", _implementor1);
            Client2 = new SuperPoolClient("client2", _implementor2);
        }
예제 #7
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public ClientEventsHandler(SuperPoolSubscription owner, SuperPoolClient client)
        {
            _owner = owner;
            if (Initialize(client) == false)
            {
#if Matrix_Diagnostics
                SystemMonitor.Error("Failed to initialize subscription for client."); SystemMonitor.ErrorIf(Initialize(client) == false, "Failed to initialize subscription for client."); SystemMonitor.ErrorIf(Initialize(client) == false, "Failed to initialize subscription for client."); SystemMonitor.Error("Failed to initialize subscription for client.");
#endif
            }
        }
예제 #8
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public ClientEventsHandler(SuperPoolSubscription owner, SuperPoolClient client)
 {
     _owner = owner;
     if (Initialize(client) == false)
     {
     #if Matrix_Diagnostics
         SystemMonitor.Error("Failed to initialize subscription for client."); SystemMonitor.ErrorIf(Initialize(client) == false, "Failed to initialize subscription for client."); SystemMonitor.ErrorIf(Initialize(client) == false, "Failed to initialize subscription for client."); SystemMonitor.Error("Failed to initialize subscription for client.");
     #endif
     }
 }
예제 #9
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);
        }
예제 #10
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public DirectCallSpeedTest()
            : base(true)
        {
            pool = new Matrix.Framework.SuperPool.Core.SuperPool();

            client1 = new SuperPoolClient("c1", this);
            client2 = new SuperPoolClient("c2", this);

            bool result = pool.AddClient(client1);
            result = pool.AddClient(client2);
        }
예제 #11
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public DirectCallSpeedTest()
            : base(true)
        {
            pool = new Matrix.Framework.SuperPool.Core.SuperPool();

            client1 = new SuperPoolClient("c1", this);
            client2 = new SuperPoolClient("c2", this);

            bool result = pool.AddClient(client1);

            result = pool.AddClient(client2);
        }
예제 #12
0
 /// <summary>
 ///
 /// </summary>
 internal bool Call <InterfaceType>(SuperPoolClient sender, ComponentId receiversIds,
                                    out InterfaceType result, out SuperPoolProxyCall call)
     where InterfaceType : class
 {
     if (receiversIds == null)
     {
         return(Call <InterfaceType>(sender, (IEnumerable <ComponentId>)null, out result, out call));
     }
     else
     {
         return(Call <InterfaceType>(sender, new ComponentId[] { receiversIds }, out result, out call));
     }
 }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        public void Dispose()
        {
            ReleaseCurrentClientSource();

            lock (this)
            {
                if (_client != null)
                {
                    _client.SourceUpdatedEvent -= new SuperPoolSourceUpdateDelegate(_client_SourceChangedEvent);
                    _client = null;
                }

                _owner = null;
            }
        }
예제 #14
0
        /// <summary>
        /// Assign and attach to the client.
        /// </summary>
        protected bool Initialize(SuperPoolClient client)
        {
            lock (this)
            {
                if (_client != null)
                {
                    return(false);
                }

                _client = client;
                _client.SourceUpdatedEvent += new SuperPoolSourceUpdateDelegate(_client_SourceChangedEvent);
            }

            AssignClientSource(client.Source);
            return(true);
        }
예제 #15
0
        /// <summary>
        /// Remove a client from the pool.
        /// </summary>
        public virtual bool RemoveClient(SuperPoolClient client, bool isPermanent)
        {
            IMessageBus messageBus = _messageBus;

            if (messageBus == null)
            {
                return(false);
            }

            bool result = messageBus.RemoveClient(client, isPermanent);

            if (result)
            {
                client.ReleaseSuperPool();
            }

            return(result);
        }
예제 #16
0
        /// <summary>
        /// Initialize the pool for operation, by supplying it with a message bus.
        /// </summary>
        protected virtual bool Initialize(IMessageBus messageBus)
        {
            lock (this)
            {
                if (_messageBus != null || messageBus == null)
                {
                    return(false);
                }

                _messageBus = messageBus;
                _messageBus.ClientAddedEvent   += new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                _messageBus.ClientRemovedEvent += new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                _messageBus.ClientUpdateEvent  += new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);

                // Add a client with self to the message bus.
                IntercomClient = new SuperPoolClient("SuperPool.Intercom", this);
            }

            if (this.AddClient(IntercomClient) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Fatal("Failed to add super pool main client.");
#endif
                lock (this)
                {
                    IntercomClient.Dispose();
                    IntercomClient = null;

                    _messageBus.ClientAddedEvent   -= new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                    _messageBus.ClientRemovedEvent -= new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                    _messageBus.ClientUpdateEvent  -= new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);
                    _messageBus = null;
                }

                return(false);
            }

            return(true);
        }
예제 #17
0
        /// <summary>
        /// Add a client to the pool.
        /// </summary>
        public virtual bool AddClient(SuperPoolClient client)
        {
            IMessageBus messageBus = _messageBus;

            if (messageBus == null)
            {
                return(false);
            }

            if (client.Source == null)
            {// TODO: clear this scenario.
             //System.Diagnostics.Debug.Fail("Warning, adding a client with no source assigned. Make sure to assign source prior to adding client.");
            }

            bool result = messageBus.AddClient(client);

            if (result)
            {
                client.AssignSuperPool((SuperPool)this);
            }

            return(result);
        }
예제 #18
0
        /// <summary>
        /// Initialize the pool for operation, by supplying it with a message bus.
        /// </summary>
        protected virtual bool Initialize(IMessageBus messageBus)
        {
            lock (this)
            {
                if (_messageBus != null || messageBus == null)
                {
                    return false;
                }

                _messageBus = messageBus;
                _messageBus.ClientAddedEvent += new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                _messageBus.ClientRemovedEvent += new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                _messageBus.ClientUpdateEvent += new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);

                // Add a client with self to the message bus.
                IntercomClient = new SuperPoolClient("SuperPool.Intercom", this);
            }

            if (this.AddClient(IntercomClient) == false)
            {
            #if Matrix_Diagnostics
                InstanceMonitor.Fatal("Failed to add super pool main client.");
            #endif
                lock (this)
                {
                    IntercomClient.Dispose();
                    IntercomClient = null;

                    _messageBus.ClientAddedEvent -= new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                    _messageBus.ClientRemovedEvent -= new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                    _messageBus.ClientUpdateEvent -= new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);
                    _messageBus = null;
                }

                return false;
            }

            return true;
        }
예제 #19
0
        /// <summary>
        /// Remove a client from the pool.
        /// </summary>
        public virtual bool RemoveClient(SuperPoolClient client, bool isPermanent)
        {
            IMessageBus messageBus = _messageBus;
            if (messageBus == null)
            {
                return false;
            }

            bool result = messageBus.RemoveClient(client, isPermanent);
            if (result)
            {
                client.ReleaseSuperPool();
            }

            return result;
        }
예제 #20
0
        /// <summary>
        /// Add a client to the pool.
        /// </summary>
        public virtual bool AddClient(SuperPoolClient client)
        {
            IMessageBus messageBus = _messageBus;
            if (messageBus == null)
            {
                return false;
            }

            if (client.Source == null)
            {// TODO: clear this scenario.
                //System.Diagnostics.Debug.Fail("Warning, adding a client with no source assigned. Make sure to assign source prior to adding client.");
            }

            bool result = messageBus.AddClient(client);
            if (result)
            {
                client.AssignSuperPool((SuperPool)this);
            }

            return result;
        }
예제 #21
0
 /// <summary>
 /// Helper version of the call, with no receiver speicified.
 /// This is utilized in events calls.
 /// </summary>
 internal bool Call <InterfaceType>(SuperPoolClient sender, out InterfaceType result, out SuperPoolProxyCall call)
     where InterfaceType : class
 {
     return(Call <InterfaceType>(sender, (IEnumerable <ComponentId>)null, out result, out call));
 }
예제 #22
0
        /// <summary>
        /// Basic asynchronous call operation.
        /// </summary>
        /// <param name="receiverId">The value of the receiver, null means call all.</param>
        internal bool Call <InterfaceType>(SuperPoolClient sender, IEnumerable <ComponentId> receiversIds,
                                           out InterfaceType result, out SuperPoolProxyCall call)
            where InterfaceType : class
        {
            call   = null;
            result = null;

            // SLOW.
            //if (_messageBus.ContainsClient(sender.Id) == false)
            //{
            //    SystemMonitor.OperationError("Client not a member of message bus (and super pool).");
            //    return false;
            //}

            if (typeof(InterfaceType).IsInterface == false)
            {
                throw new Exception("Type provided not an interface.");
            }

            // Very slow !!
            //object[] attributes = typeof(InterfaceType).GetCustomAttributes(typeof(SuperPoolInterfaceAttribute), false);
            //if (attributes == null || attributes.Length == 0)
            //{
            //    SystemMonitor.Throw("Interface type [" + typeof(InterfaceType).Name + "] not marked as super pool interface.");
            //    return false;
            //}

            ProxyTypeManager typeManager = _proxyTypeManager;

            if (typeManager == null)
            {
                return(false);
            }

            if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out call) == false)
            {// We are safe from danger of someone else already adding the value with this id,
                // since we are the only thread with this id.
                call = new SuperPoolProxyCall();
                // This is slow, but very rarely executed, since thread ids are reused.
                _pendingThreadsCalls.Add(Thread.CurrentThread.ManagedThreadId, call);
            }
            else
            {
                // Since we reuse the call, clean it up before usage.
                call.Clear();
            }

            call.Processed = false;
            if (receiversIds != null)
            {// Extract the Indeces from the Ids.
                List <ClientId> receiversIndeces = new List <ClientId>();
                foreach (ComponentId id in receiversIds)
                {
                    receiversIndeces.Add((ClientId)id);
                }

                call.ReceiversIds = receiversIndeces;
            }
            else
            {
                call.ReceiversIds = null;
            }

            call.Sender = sender;

            result = (InterfaceType)typeManager.ObtainInterfaceProxy(typeof(InterfaceType));

            return(true);
        }
예제 #23
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //// [Optional] Assign the default tracer, to provide system wide tracing functionality.
            //SystemMonitor.AssignTracer(new Tracer());
            //this.tracerControl1.Tracer = SystemMonitor.Tracer;

            // Create the underlying (server) message bus and put the pool on it.
            ServerMessageBus messageBus = new ServerMessageBus("Server", null, null);
            _pool = new Matrix.Framework.SuperPool.Core.SuperPool(messageBus);

            // Create the client that will server as a connection between this
            // class and the super pool and add the client to the pool.
            _poolClient = new SuperPoolClient("Server", this);
            _pool.AddClient(_poolClient);

            // Finally subscribe to the event of having a client added to the bus/pool.
            _pool.MessageBus.ClientAddedEvent += new MessageBus.Core.MessageBusClientUpdateDelegate(MessageBus_ClientAddedEvent);
            messageBus.ClientRemovedEvent += (bus, id, remove) =>
            {
                this.Invoke(new GeneralHelper.GenericDelegate<string>(Report),
                            "Client removed " + id.ToString());
            };
        }
예제 #24
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Text += " - " + this.ClientName;

            // The steps here are exactly the same, as in server side, only difference is the ClientMessageBus
            // instead of ServerMessageBus. Since this is the only difference, all the remaining source code
            // is completely independent of whether its a server or a client side.

            //// Assign the default tracer, to provide system wide tracing functionality.
            //SystemMonitor.AssignTracer(new Tracer());
            //this.tracerControl1.Tracer = SystemMonitor.Tracer;

            IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, ServerMessageBus.DefaultPort);

            // Create the underlying (client) message bus, that takes care of transporting the
            // actual communication messages; the message bus TCP communication is created
            // at default port, at localhost.
            ClientMessageBus messageBus = new ClientMessageBus(endPoint, this.ClientName, null);

            // Initialize the super pool with this message bus.
            _pool = new Matrix.Framework.SuperPool.Core.SuperPool(messageBus);

            // Create the client that will server as a connection between this
            // class and the super pool and add the client to the pool.
            _poolClient = new SuperPoolClient("Client." + this.ClientName, this);
            _pool.AddClient(_poolClient);

            // Use this to assign a specific execution strategy to a given client.
            // _poolClient.SetupExecutionStrategy(new FrameworkThreadPoolExecutionStrategy());
        }
예제 #25
0
        public void AcceptResponse(SuperPoolClient client, object result, Exception exception)
        {
            Response = result;

            if (AsyncResultDelegate != null)
            {
                try
                {
                    AsyncResultDelegate.Invoke(client, new AsyncResultParams() { Result = result, State = AsyncResultState, Exception = exception });
                }
                catch (Exception ex)
                {
            #if Matrix_Diagnostics
                    SystemMonitor.OperationError(string.Format("AcceptReposnse invoke of client [{0}] has caused an exception", client.Name), ex);
            #endif
                }
            }
            else
            {// Assign the parameter only in sync calls, since async already consumed it trough async delegate.
                Exception = exception;
            }

            ManualResetEvent eventInstance = Event;
            if (eventInstance != null)
            {
                eventInstance.Set();
            }
        }
예제 #26
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public MyComponent()
 {
     Client = new SuperPoolClient("MyClient", this);
 }
 /// <summary>
 /// Contructor.
 /// </summary>
 public Component(string name)
 {
     client = new SuperPoolClient(name, this);
 }
예제 #28
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);
            }
        }
예제 #29
0
        protected override bool HandleClientAdded(IMessageBus messageBus, ClientId clientId)
        {
            // Make sure to have this done first, since it will send notifications of clients, and we
            // may need those for the establishment of events.
            if (base.HandleClientAdded(messageBus, clientId) == false || messageBus == null || clientId == null)
            {
                return(false);
            }

            MessageBusClient clientInstance = messageBus.GetLocalClientInstance(clientId);

            // Will only work for local AND MessageSuperPoolClient typed clients.
            if (clientInstance is SuperPoolClient)
            {
                lock (_syncRoot)
                {
                    if (_clients.ContainsKey(clientInstance.Id))
                    {// Already added.
                        return(false);
                    }

                    ClientEventsHandler subscription = new ClientEventsHandler(this, (SuperPoolClient)clientInstance);
                    _clients.Add(clientInstance.Id, subscription);
                }
            }
            else
            {
                List <string> sourceTypeNames = messageBus.GetClientSourceTypes(clientId);
                if (sourceTypeNames == null)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.Error("Failed to obtain client [" + clientId.ToString() + "] source type.");
#endif
                    return(false);
                }

                SuperPoolClient intercomClient = IntercomClient;
                if (intercomClient == null)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.Error("Failed to obtain super pool main intercom client, so new client handling has failed.");
#endif
                    return(false);
                }

                List <EventSubscriptionRequest> totalRequests = new List <EventSubscriptionRequest>();
                if (clientId.IsLocalClientId == false)
                {
                    // Gather all the Super Pool related interfaces and their events, and send global updates for those
                    // so that any pending subscriptions may be restored.
                    // This is only done where the client is a remote client instance, since local ones we already know
                    // of them. This eventing information must be at the local pool for the client, since it is the one
                    // handling the event and sending it to all interested parties.
                    foreach (Type interfaceType in ReflectionHelper.GetKnownTypes(sourceTypeNames))
                    {
                        if (interfaceType.IsInterface &&
                            ReflectionHelper.TypeHasCustomAttribute(interfaceType, typeof(SuperPoolInterfaceAttribute), false) == false)
                        {// Interface type not marked as super pool.
                            continue;
                        }

                        foreach (EventInfo info in interfaceType.GetEvents())
                        {
                            string eventName = GeneralHelper.GetEventMethodExtendedName(info, false);
                            EventSubscriptionInfo eventInfo;
                            if (_eventSubscriptions.TryGetValue(eventName, out eventInfo))
                            {
                                totalRequests.AddRange(eventInfo.GatherSourceRelatedUpdates(clientId));
                            }
                        }
                    }
                }

                // Send updates for the newly connected client, so that it can obtain any subscription information
                // regarding it, it case it has missed some.
                foreach (EventSubscriptionRequest request in totalRequests)
                {
                    // 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*
                    intercomClient.CallAll <ISuperPoolIntercom>().ProcessSubscriptionUpdate(request);
                }
            }


            return(true);
        }
예제 #30
0
        /// <summary>
        /// Constructor.
        /// </summary>
        internal CallTestImplementor()
        {
            _implementor1 = new InterfaceImplementor("Implementor1");
            _implementor2 = new InterfaceImplementor("Implementor2");

            Client1 = new SuperPoolClient("client1", _implementor1);
            Client2 = new SuperPoolClient("client2", _implementor2);
        }
예제 #31
0
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            ReleaseCurrentClientSource();

            lock (this)
            {
                if (_client != null)
                {
                    _client.SourceUpdatedEvent -= new SuperPoolSourceUpdateDelegate(_client_SourceChangedEvent);
                    _client = null;
                }

                _owner = null;
            }
        }
예제 #32
0
        protected void AssignClientSource(object source)
        {
            SuperPoolClient client = _client;

            if (client == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.Error("Failed to add client source, since client not available (possible Dispose).");
#endif
                return;
            }

            SuperPoolSubscription owner = _owner;
            if (owner == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.Error("Failed to add client source, since no owner is available (possible Dispose).");
#endif
                return;
            }

            ReleaseCurrentClientSource();

            _clientSource = source;

            if (_clientSource == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationWarning("Starting a client with no source attached.");
#endif
                return;
            }

            foreach (Type interfaceType in ReflectionHelper.GatherTypeAttributeMarkedInterfaces(source.GetType(), typeof(SuperPoolInterfaceAttribute)))
            {// Gather all events, from interfaces marked with [SuperPoolInterfaceAttribute].
                // Make sure to have created the corresponding proxy instance for this interface type.
                owner.ProxyTypeManager.ObtainInterfaceProxy(interfaceType);

                foreach (EventInfo eventInfo in interfaceType.GetEvents())
                {
                    Type delegateType = eventInfo.EventHandlerType;
                    GeneratedMethodInfo methodInfo = owner.ProxyTypeManager.Builder.GenerateDynamicMethodProxyDelegate(delegateType);

                    // Create delegate can operate in 2 modes:
                    // - create a static delegate like this (requires instnace upon call): info.Method.CreateDelegate(delegateType);
                    // - create an instance delegate like this (can be direct called): info.Method.CreateDelegate(delegateType, instance);

                    Delegate delegateInstance = methodInfo.StandaloneDynamicMethod.CreateDelegate(delegateType, this);
                    eventInfo.AddEventHandler(source, delegateInstance);

                    EventHandlingInformation subscriptionInfo = new EventHandlingInformation()
                    {
                        DelegateInstance    = delegateInstance,
                        EventInfo           = eventInfo,
                        GeneratedMethodInfo = methodInfo
                    };

                    lock (this)
                    {
                        _eventsMethods.Add(methodInfo.Id, subscriptionInfo);
                    }
                }
            }
        }
예제 #33
0
        /// <summary>
        /// Assign and attach to the client.
        /// </summary>
        protected bool Initialize(SuperPoolClient client)
        {
            lock (this)
            {
                if (_client != null)
                {
                    return false;
                }

                _client = client;
                _client.SourceUpdatedEvent += new SuperPoolSourceUpdateDelegate(_client_SourceChangedEvent);
            }

            AssignClientSource(client.Source);
            return true;
        }
예제 #34
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public MyComponent()
 {
     Client = new SuperPoolClient("MyClient", this);
 }