/// <summary>
            /// Constructor.
            /// </summary>
            public TargetInfo(string invokerName, object target, FastInvokeHelper.FastInvokeHandlerDelegate delegateInstance,
                              bool poolAsFirstParameter, ThreadPoolFast pool, params object[] args)
            {
                DelegateInstance = delegateInstance;
                Target           = target;
                InvokerName      = invokerName;

                if (poolAsFirstParameter)
                {
                    Args = new object[] { pool, args };
                }
                else
                {
                    Args = args;
                }

                //if (args != null && args.Length == 1)
                //{// Single parameter pass.
                //    Args = new object[] { pool, args[0] };
                //}
                //else
                //{
                //    Args = new object[] { pool, args };
                //}
            }
        /// <summary>
        /// Constructor.
        /// </summary>
        public ThreadPoolFastExecutionStrategy(bool useCommonMessageBusPool)
        {
            _useCommonMessageBusPool = useCommonMessageBusPool;

            GeneralHelper.GenericDelegate<Envelope> delegateInstance = new GeneralHelper.GenericDelegate<Envelope>(PerformExecution);
            _performExecutionDelegate = FastInvokeHelper.GetMethodInvoker(delegateInstance.Method, true, false);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public ThreadPoolFastExecutionStrategy(bool useCommonMessageBusPool)
        {
            _useCommonMessageBusPool = useCommonMessageBusPool;

            GeneralHelper.GenericDelegate <Envelope> delegateInstance = new GeneralHelper.GenericDelegate <Envelope>(PerformExecution);
            _performExecutionDelegate = FastInvokeHelper.GetMethodInvoker(delegateInstance.Method, true, false);
        }
        /// <summary>
        /// Enqueue a target and Fast Invoke delegate instance for execution.
        /// *IMPORTANT* make sure to store the delegateInstance and reuse it over multiple calls!
        /// </summary>
        public void QueueFastDelegate(object target, bool poolAsFirstParameter, FastInvokeHelper.FastInvokeHandlerDelegate delegateInstance,
                                      params object[] args)
        {
            ThreadPoolFastEx.TargetInfo targetInfo = new ThreadPoolFastEx.TargetInfo(string.Empty,
                                                                                     target, delegateInstance, poolAsFirstParameter, this, args);

            QueueTargetInfo(targetInfo);
        }
Beispiel #5
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public ThreadPoolFastExecutionStrategy(ArbiterSlimActiveClientStub client, bool useCommonArbiterPool)
            : base(client)
        {
            _useCommonArbiterPool = useCommonArbiterPool;

            GeneralHelper.GenericDelegate <ThreadPoolFast, Envelope> delegateInstance = new GeneralHelper.GenericDelegate <ThreadPoolFast, Envelope>(PerformExecution);
            _singleFastInvokeDelegate = FastInvokeHelper.GetMethodInvoker(delegateInstance.Method, false);
        }
        /// <summary>
        /// Helper, obtain the correspoding fast delegate of a method info.
        /// </summary>
        public FastInvokeHelper.FastInvokeHandlerDelegate GetMessageHandler(MethodInfo methodInfo)
        {
            lock (_methodDelegates)
            {
                if (_methodDelegates.ContainsKey(methodInfo))
                {
                    return(_methodDelegates[methodInfo]);
                }

                FastInvokeHelper.FastInvokeHandlerDelegate resultHandler = FastInvokeHelper.GetMethodInvoker(methodInfo, true);
                _methodDelegates[methodInfo] = resultHandler;
                return(resultHandler);
            }
        }
Beispiel #7
0
        /// <summary>
        /// This is an entry point for the direct call mechanism. So optimization is on speed and not functionality.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public override Message ReceiveDirectCall(Message message)
        {
            FastInvokeHelper.FastInvokeHandlerDelegate handler = GetMessageHandler(message);
            if (handler != null)
            {
                return((Message)handler(this, new object[] { message }));
            }
            else
            {// We failed to find a handler for this type or for any of the parent ones.
                TracerHelper.TraceError("Client instance did not handle a request message received, client [" + this.GetType().Name + "], message [" + message.GetType().Name + "].");
                return(null);
            }

            //Message responceMessage = (Message)invokeMethodInfo.Invoke(this, new object[] { message });
            //return responceMessage;
        }
Beispiel #8
0
        /// <summary>
        /// Helper class, to establish the delegate that handles this message.
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        protected FastInvokeHelper.FastInvokeHandlerDelegate GetMessageHandler(Message message)
        {
            FastInvokeHelper.FastInvokeHandlerDelegate resultHandler = null;

            Type messageType = message.GetType();

            lock (_methodsAndMessageTypes)
            {
                Type currentType = messageType;
                while (currentType != typeof(Message) && currentType != typeof(object))
                {// Look for a handler of this requestMessage type or for any of the parent types.
                    if (_methodsAndMessageTypes.ContainsKey(currentType))
                    {
                        resultHandler = _methodsAndMessageTypes[currentType];
                        break;
                    }

                    currentType = currentType.BaseType; // FIX, Asen: it used to be messageType.BaseType.
                }
            }

            return(resultHandler);
        }
Beispiel #9
0
        /// <summary>
        /// Handle a request message.
        /// </summary>
        protected virtual void HandleRequestMessage(TransportMessage message)
        {
            FastInvokeHelper.FastInvokeHandlerDelegate handler = GetMessageHandler(message);

            if (handler == null)
            {// We failed to find a handler for this type or for any of the parent ones.
                TracerHelper.TraceError("Client instance did not handle a request message received, client [" + this.GetType().Name + "], message [" + message.GetType().Name + "].");
                return;
            }

            // Before giving the requestMessage to the user class, make a copy of its transport info
            // so that if the user messes it up, we still can deliver the responce properly.
            TransportInfo requestMessageTransportInfo = message.TransportInfo.Clone();

            TransportMessage responseMessage = (TransportMessage)handler(this, new object[] { message });

            if (responseMessage == null)
            {// No result.
                return;
            }

            if (responseMessage is ResponseMessage)
            {
                ((ResponseMessage)responseMessage).RequestMessageTypeName = message.GetType().Name;
            }

            Guid            sessionGuid = requestMessageTransportInfo.CurrentTransportInfo.Value.Id;
            ArbiterClientId?senderID    = requestMessageTransportInfo.CurrentTransportInfo.Value.SenderID;

            requestMessageTransportInfo.PopTransportInfo();

            // Transfer inherited underlaying transport stack.
            responseMessage.TransportInfo = requestMessageTransportInfo;

            // Send the responce requestMessage back.
            DoSendCustom(false, sessionGuid, null, 0, senderID, this.SubscriptionClientID, responseMessage, TimeSpan.Zero);
        }
 /// <summary>
 /// Enqueue a target and Fast Invoke delegate instance for execution.
 /// *IMPORTANT* make sure to store the delegateInstance and reuse it over multiple calls!
 /// </summary>
 public void QueueFastDelegate(object target, FastInvokeHelper.FastInvokeHandlerDelegate delegateInstance,
                               params object[] args)
 {
     QueueFastDelegate(target, false, delegateInstance, args);
 }
Beispiel #11
0
        /// <summary>
        /// A call has been made from us trough the proxy object.
        /// </summary>
        internal object ProcessCall(SuperPoolProxyCall proxyCall)
        {
            SuperPoolInvocation superPool = _superPool;

            if (superPool == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationError("Failed to find super pool (possible dispose).");
#endif
                return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
            }

            IMessageBus messageBus = superPool.MessageBus;
            if (messageBus == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationError("Failed to find message bus (possible dispose).");
#endif
                return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
            }

            if (proxyCall.Processed)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationError("Proxy call already processed.");
#endif
                return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
            }

            if (proxyCall.Mode == SuperPoolProxyCall.ModeEnum.DirectCall)
            {
                MessageBusClient clientInstance = messageBus.GetLocalClientInstance(proxyCall.ReceiversIds[0]);
                if (clientInstance == null || clientInstance is SuperPoolClient == false)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError("Direct call failed, due to client not found or corresponding.");
#endif
                    return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                }
                else
                {// Perform the direct call.
                    // This is still fast, since caching is used.
                    FastInvokeHelper.FastInvokeHandlerDelegate delegateInstance = FastInvokeHelper.GetMethodInvoker(proxyCall.MethodInfo.ProxyMethodInfo, true, true);
                    return(delegateInstance.Invoke(((SuperPoolClient)clientInstance).Source, proxyCall.Parameters));
                }
            }
            else if (proxyCall.Mode == SuperPoolProxyCall.ModeEnum.CallFirst)
            {
                ClientId firstId = this.Resolve(proxyCall.MethodInfo.ProxyMethodInfo.DeclaringType);
                if (firstId == null)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError("Call first failed, no client found for [" + proxyCall.MethodInfo.ProxyMethodInfo.DeclaringType.Name + "] interface.");
#endif

                    return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                }

                proxyCall.ReceiversIds = new List <ClientId>()
                {
                    firstId
                };
            }

            SuperPoolCall call = new SuperPoolCall(superPool.GetUniqueCallId());

            call.Parameters      = proxyCall.Parameters;
            call.MethodInfoLocal = proxyCall.MethodInfo.ProxyMethodInfo;

            call.State = SuperPoolCall.StateEnum.Requesting;
            //SuperPoolProxyCall.ModeEnum.Default ? SuperPoolCall.StateEnum.Requesting : SuperPoolCall.StateEnum.RequestingDirectCall;

            call.RequestResponse = proxyCall.IsSynchronous || proxyCall.IsAsyncResultExpecting;

            proxyCall.Processed = true;

            foreach (ParameterInfo info in call.MethodInfoLocal.GetParameters())
            {// Filter out ref, out and optional parameters.
                if (/*info.IsOptional ||*/ info.IsOut || info.IsRetval || info.IsOut || info.ParameterType.IsByRef)
                {
                    throw new NotImplementedException("Super pool calls do not support optional, out and ref parameters");
                }
            }

            // Prepare the synchronous structure (also handles waiting for the async results).
            SyncCallInfo syncCall = null;
            if (proxyCall.IsSynchronous || proxyCall.IsAsyncResultExpecting)
            {
                syncCall = new SyncCallInfo(call.Id)
                {
                    AsyncResultState    = proxyCall.AsyncResultState,
                    AsyncResultDelegate = proxyCall.AsyncResultDelegate,
                    AsyncResultTimeout  = proxyCall.AsyncResultTimeout,
                };

                lock (_syncCalls)
                {
                    _syncCalls[call.Id] = syncCall;
                }
            }

            List <ClientId> receiversIndeces = null;
            if (proxyCall.ReceiversIds == null)
            {// No receiver indicates send to all, so that is what we do.
                if (proxyCall.MethodInfo == null || proxyCall.MethodInfo.ProxyOwnerType == null)
                {
#if Matrix_Diagnostics
                    SystemMonitor.Error("Failed to establish the required proxy call parameters.");
#endif
                    return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                }

                Type interfaceType = proxyCall.MethodInfo.GetBaseInterfaceType();
                if (interfaceType == null)
                {
#if Matrix_Diagnostics
                    SystemMonitor.Error("Failed to establish the base interface type.");
#endif
                    return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                }

                receiversIndeces = new List <ClientId>();
                foreach (ComponentId receiverId in superPool.GetInterfaceImplementors(interfaceType))
                {
                    if (receiverId != proxyCall.Sender.Id)
                    {
                        receiversIndeces.Add((ClientId)receiverId);
                    }

                    if (proxyCall.IsSynchronous && receiversIndeces.Count > 0)
                    {// Synchronous inadressed calls only execute agains a max of one provider.
                        break;
                    }
                }
            }
            else
            {
                receiversIndeces = proxyCall.ReceiversIds;
            }

            if (receiversIndeces.Count > 0)
            {
                if (syncCall != null && proxyCall.IsSynchronous)
                {// Prepare the event.
                    syncCall.Event = new ManualResetEvent(false);
                }

                Outcomes sendResult = messageBus.Send(this.Id, receiversIndeces, new Envelope(call)
                {
                    DuplicationMode = EnvelopeDuplicationMode
                }, proxyCall.RequestConfirmTimeout, false);

                if (proxyCall.Outcome != null)
                {
                    proxyCall.Outcome.Result = sendResult;
                }

                if (sendResult != Outcomes.Success)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError(string.Format("Failed to send proxy call [{0}].", proxyCall.ToString()));
#endif
                    return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                }

                if (syncCall != null && proxyCall.IsSynchronous)
                {     // Wait for response.
                    if (syncCall.Event.WaitOne(proxyCall.Timeout.Value) == false)
                    { // Time out.
#if Matrix_Diagnostics
                        SystemMonitor.OperationWarning(string.Format("Proxy call timed out [{0}].", proxyCall.ToString()));
#endif
                        return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
                    }
                    else
                    {// Waited and awaken.
                        return(syncCall.Response);
                    }
                }
            }
            else
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationWarning(string.Format("Failed to find invocation recipients for call [{0}].", proxyCall.ToString()));
#endif
            }

            return(ProxyTypeManager.GetTypeDefaultValue(proxyCall.ReturnType));
        }
            /// <summary>
            /// Constructor.
            /// </summary>
            public TargetInfo(string invokerName, object target, FastInvokeHelper.FastInvokeHandlerDelegate delegateInstance,
                bool poolAsFirstParameter, ThreadPoolFast pool, params object[] args)
            {
                DelegateInstance = delegateInstance;
                Target = target;
                InvokerName = invokerName;

                if (poolAsFirstParameter)
                {
                    Args = new object[] { pool, args };
                }
                else
                {
                    Args = args;
                }

                //if (args != null && args.Length == 1)
                //{// Single parameter pass.
                //    Args = new object[] { pool, args[0] };
                //}
                //else
                //{
                //    Args = new object[] { pool, args };
                //}
            }