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