示例#1
0
        /// <summary>
        /// Obtain the next execution entity and remove it from pending.
        /// Children to override to manage the way operations are performed, if they need to.
        /// This is where currently the MultiThreads per client protection is performed.
        /// </summary>
        protected virtual ExecutionEntity PopNextExecutionEntity()
        {
            lock (this)
            {
                // Check total executioners count.
                if (_threadPool.FreeThreadsCount < 2)
                {
                    //if ((DateTime.Now - _executionersBusyWarningShownTime) >= _warningsTimeSpan)
                    {
                        SystemMonitor.OperationError("All of the [" + _threadPool.MaximumSimultaniouslyRunningThreadsAllowed + "] arbiter [" + _arbiter.Name + "] executioners are busy, entity execution delayed.", TracerItem.PriorityEnum.Medium);
                        //_executionersBusyWarningShownTime = DateTime.Now;
                    }

                    return(null);
                }

                // Try looking for a new entity.
                for (int i = 0; i < _pendingEntities.Count; i++)
                {// Look for an entity that we are allowed to execute now.
                    ExecutionEntity entity  = _pendingEntities[i];
                    IArbiterClient  iClient = _arbiter.GetClientByID(entity.ReceiverID);

                    bool isTransportResponceMessage = (entity.Message is TransportMessage &&
                                                       ((TransportMessage)(entity.Message)).IsRequest == false);

                    int runningOnClient = 0;
                    if (_clientsRunningExecutioners.ContainsKey(entity.ReceiverID))
                    {
                        runningOnClient = _clientsRunningExecutioners[entity.ReceiverID];
                    }

                    if (isTransportResponceMessage == false && iClient != null &&
                        iClient.SingleThreadMode && runningOnClient > 0 /*_executionersAndClientIDs.ContainsValue(entity.ReceiverID)*/)
                    {// We are not allowed to run this, as there is already an executioner there.
                        // And it is not a responce requestMessage.
                        continue;
                    }

                    if (runningOnClient >= _maxExecutionersPerEntity)
                    {// This entity is already consuming too many threads. It must release some before using more.
                        //if ((DateTime.Now - _executionersBusyWarningShownTime) >= _warningsTimeSpan)
                        {
                            //_executionersBusyWarningShownTime = DateTime.Now;
                            SystemMonitor.OperationError("An entity [" + entity.ReceiverID.Id.Name + "] is using all its threads allowed. Further entity executions will be delayed.", TracerItem.PriorityEnum.Medium);
                        }

                        continue;
                    }

                    //TraceHelper.Trace("PopNextExecutionEntity [" + iClient.ToString() + "][" + iClient.SingleThreadMode + "," + _executionersAndClientIDs.ContainsValue(entity.ReceiverID) + "][" + entity.Message.ToString() + "]");

                    _pendingEntities.Remove(entity);

                    // OK, this entity is good to go.
                    return(entity);
                }

                return(null);
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public ArbiterSlimActiveClientStub(IArbiterClient client, ArbiterSlimExecutionStrategy executionStrategy)
        {
            _client            = client;
            _executionStrategy = executionStrategy;

            SystemMonitor.CheckThrow(executionStrategy != null, "Execution strategy not assigned.");

            Construct();
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public ArbiterSlimActiveClientStub(IArbiterClient client)
        {
            _client = client;

            //_executionStrategy = new FrameworkThreadPoolExecutionStrategy(this);
            _executionStrategy = new ThreadPoolFastExecutionStrategy(this, true);

            Construct();
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 public ArbiterClientId(string name, Type identifiedType, IArbiterClient optionalReference)
 {
     _optionalReference = optionalReference;
     _sessionTag        = string.Empty;
     _id = new ComponentId()
     {
         Guid = Guid.NewGuid(), Name = name, IdentifiedComponentType = identifiedType
     };
 }
示例#5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="parameter0"></param>
        protected void _timeOutMonitor_EntityTimedOutEvent(TimeOutable parameter0)
        {
            Conversation   conversation = (Conversation)parameter0;
            IArbiterClient client       = GetClientByID(conversation.OwnerID, false);

            if (client != null)
            {
                client.ReceiveConversationTimedOut(conversation);
            }
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public bool RemoveClient(IArbiterClient client)
        {
            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return(false);
            }

            lock (_clientsAndFilters)
            {
                client.ArbiterUnInitialize();
                return(_clientsAndFilters.Remove(client) && _clientsIdsAndClients.Remove(client.SubscriptionClientID));
            }
        }
示例#7
0
        /// <summary>
        /// Add a client to the arbiter, will raise the ClientAddedEvent if successful.
        /// </summary>
        public bool AddClient(IArbiterClient client)
        {
            if (client == null || GetClientByID(client.SubscriptionClientID, false) != null)
            {
                return(false);
            }

            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return(false);
            }

            lock (_clientsAndFilters)
            {
                if (_clientsAndFilters.ContainsKey(client))
                {
                    return(false);
                }
                _clientsAndFilters.Add(client, client.SubscriptionMessageFilter);
            }

            lock (_clientsIdsAndClients)
            {
                _clientsIdsAndClients.Add(client.SubscriptionClientID, client);
            }

            if (client.ArbiterInitialize(this) == false || _isDisposed)
            {
                lock (_clientsAndFilters)
                {
                    _clientsAndFilters.Remove(client);
                }

                lock (_clientsIdsAndClients)
                {
                    _clientsIdsAndClients.Remove(client.SubscriptionClientID);
                }

                SystemMonitor.OperationError("Client failed arbiter initialialization [" + client.Name + "]");
                return(false);
            }

            ClientManagerClientUpdateDelegate clientAddedDelegate = ClientAddedEvent;

            if (clientAddedDelegate != null)
            {
                clientAddedDelegate(this, client);
            }

            return(true);
        }
示例#8
0
        /// <summary>
        /// The direct call allows to circumvent the many steps (incl serialization) of typical message sending
        /// and make a direct call to another Arbiter member; thus making a much faster delivery. This path
        /// has a maximum optimization for speed, so tracing etc. are disabled.
        ///
        /// Also this mechanism only works for TransportClients currently.
        ///
        /// The mechanism does not utilize any new threads, and the execution is performed on the calling thread.
        ///
        /// Direct calls can only be made to participants on the same arbiter, and no addressing is applied
        /// for the messages.
        /// </summary>
        public Message DirectCall(ArbiterClientId senderID, ArbiterClientId receiverID, Message message)
        {
            IArbiterClient receiver = GetClientByID(receiverID, true);

            if (receiver == null || receiver is TransportClient == false)
            {
                SystemMonitor.OperationWarning("Sender [" + senderID.Id.Print() + "] creating conversation message [" + message.GetType().Name + " ] by not present receiver [" + receiverID.Id.Print() + "] or receiver not a TransportClient");
                return(null);
            }

            Message response = receiver.ReceiveDirectCall(message);

            return(response);
        }
示例#9
0
        /// <summary>
        /// Add a client to the arbiter, will raise the ClientAddedEvent if successful.
        /// </summary>
        public bool AddClient(IArbiterClient client)
        {
            if (client == null || GetClientByID(client.SubscriptionClientID, false) != null)
            {
                return false;
            }

            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return false;
            }

            lock (_clientsAndFilters)
            {
                if (_clientsAndFilters.ContainsKey(client))
                {
                    return false;
                }
                _clientsAndFilters.Add(client, client.SubscriptionMessageFilter);
            }

            lock (_clientsIdsAndClients)
            {
                _clientsIdsAndClients.Add(client.SubscriptionClientID, client);
            }

            if (client.ArbiterInitialize(this) == false || _isDisposed)
            {
                lock (_clientsAndFilters)
                {
                    _clientsAndFilters.Remove(client);
                }

                lock (_clientsIdsAndClients)
                {
                    _clientsIdsAndClients.Remove(client.SubscriptionClientID);
                }

                SystemMonitor.OperationError("Client failed arbiter initialialization [" + client.Name + "]");
                return false;
            }

            ClientManagerClientUpdateDelegate clientAddedDelegate = ClientAddedEvent;
            if (clientAddedDelegate != null)
            {
                clientAddedDelegate(this, client);
            }

            return true;
        }
示例#10
0
        /// <summary>
        /// Remove the client from the arbiter (will raise the ClientRemovedEvent if successful).
        /// </summary>
        public bool RemoveClient(IArbiterClient client)
        {
            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return(false);
            }

            bool result = false;

            lock (_clientsAndFilters)
            {
                client.ArbiterUnInitialize();
                result = _clientsAndFilters.Remove(client) && _clientsIdsAndClients.Remove(client.SubscriptionClientID);
            }

            ClientManagerClientUpdateDelegate clientRemovedDelegate = ClientRemovedEvent;

            if (result && clientRemovedDelegate != null)
            {
                clientRemovedDelegate(this, client);
            }

            return(result);
        }
示例#11
0
 void arbiter_ClientRemovedEvent(IArbiterClientManager manager, IArbiterClient client)
 {
     RemoveClient(client.Slim);
 }
示例#12
0
 void arbiter_ClientAddedEvent(IArbiterClientManager manager, IArbiterClient client)
 {
     AddClient(client.Slim);
 }
示例#13
0
        /// <summary>
        ///
        /// </summary>
        void worker_DoWork(ExecutionEntity entity)
        {
            lock (this)
            {
                if (_clientsRunningExecutioners.ContainsKey(entity.ReceiverID) == false)
                {
                    _clientsRunningExecutioners[entity.ReceiverID] = 1;
                }
                else
                {
                    _clientsRunningExecutioners[entity.ReceiverID] = _clientsRunningExecutioners[entity.ReceiverID] + 1;
                }
            }

            TracerHelper.Trace(" Enlisted entity at [" + entity.ReceiverID.Id.Name + "]");

            DateTime startTime = DateTime.Now;

            TracerHelper.TraceEntry("entity starting [" + entity.Message.GetType().Name + ", " +
                                    entity.ReceiverID.Id.Name + "], total count [" + _threadPool.ActiveRunningThreadsCount.ToString() + "]");

            // Notify executor we are running this entity.
            entity.Conversation.EntityExecutionStarted(entity);

            try
            {
                IArbiterClient receiver = _arbiter.GetClientByID(entity.ReceiverID);
                if (receiver != null)
                {
                    SystemMonitor.CheckError(((TransportMessage)entity.Message).TransportInfo.TransportInfoCount > 0);

                    // Do the entity.
                    if (entity is ExecutionEntityWithReply)
                    {
                        ExecutionEntityWithReply replyEntity = (ExecutionEntityWithReply)entity;
                        SystemMonitor.CheckError(replyEntity.ReplyMessage == null && replyEntity.ReplyTimeOut == TimeSpan.Zero);
                        receiver.ReceiveExecutionWithReply(replyEntity);
                    }
                    else
                    {
                        SystemMonitor.CheckError(entity.GetType() == typeof(ExecutionEntity));
                        receiver.ReceiveExecution(entity);
                    }
                    entity.Conversation.EntityExecutionFinished(entity);
                }
            }
            catch (TargetInvocationException exception)
            {
                if (exception.InnerException is ThreadInterruptedException)
                {// ThreadInterruptedException's are OK, since we use them to awake sleeping threads when closing down.
                    SystemMonitor.Report(exception.ToString() + "[" + exception.InnerException.Message + "]");
                    entity.Conversation.EntityExecutionFailed(entity, exception);
                }
                else
                {
                    SystemMonitor.OperationError(exception.ToString() + "[" + exception.InnerException.Message + "]");
                    entity.Conversation.EntityExecutionFailed(entity, exception);
                }
            }
            catch (ThreadInterruptedException exception)
            {
                // ThreadInterruptedException's are OK, since we use them to awake sleeping threads when closing down.
                SystemMonitor.Report(exception.ToString() + "[" + exception.Message + "]");
                entity.Conversation.EntityExecutionFailed(entity, exception);
            }
            catch (Exception exception)
            {
                SystemMonitor.Error(exception.ToString());
                entity.Conversation.EntityExecutionFailed(entity, exception);
            }
            finally
            {
                entity.Die();
            }

            lock (this)
            {
                if (_clientsRunningExecutioners.ContainsKey(entity.ReceiverID))
                {
                    int newClientsValue = _clientsRunningExecutioners[entity.ReceiverID] - 1;
                    if (newClientsValue <= 0)
                    {
                        _clientsRunningExecutioners.Remove(entity.ReceiverID);
                    }
                    else
                    {
                        _clientsRunningExecutioners[entity.ReceiverID] = newClientsValue;
                    }
                }
                else
                {
                    if (IsDisposed == false)
                    {
                        SystemMonitor.Error("ClientsRunningExecutioners not properly maintained.");
                    }
                }

                TracerHelper.TraceExit("entity finished for [" + (DateTime.Now - startTime).Milliseconds + "]ms [" + entity.Message.GetType().Name + ", " + entity.ReceiverID.Id.Name + "], total count [" + _threadPool.ActiveRunningThreadsCount.ToString() + "]");
            }

            // Continue execution chain.
            UpdatePendingExecution();
        }
示例#14
0
        /// <summary>
        /// Remove the client from the arbiter (will raise the ClientRemovedEvent if successful).
        /// </summary>
        public bool RemoveClient(IArbiterClient client)
        {
            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return false;
            }

            bool result = false;
            lock (_clientsAndFilters)
            {
                client.ArbiterUnInitialize();
                result = _clientsAndFilters.Remove(client) && _clientsIdsAndClients.Remove(client.SubscriptionClientID);
            }

            ClientManagerClientUpdateDelegate clientRemovedDelegate = ClientRemovedEvent;
            if (result && clientRemovedDelegate != null)
            {
                clientRemovedDelegate(this, client);
            }

            return result;
        }
示例#15
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public bool RemoveClient(IArbiterClient client)
        {
            if (_isDisposed)
            {// Possible to get disposed while operating here.
                return false;
            }

            lock (_clientsAndFilters)
            {
                client.ArbiterUnInitialize();
                return _clientsAndFilters.Remove(client) && _clientsIdsAndClients.Remove(client.SubscriptionClientID);
            }
        }