public void Tick()
        {
            if (m_nextTimeoutCheck == m_tick)
            {
                if (m_requests.Count > 0)
                {
                    var keys = m_requests.Keys;
                    foreach (var key in keys)
                    {
                        PendingClientRequest request = m_requests[key];
                        if (request.TimeoutTick <= m_tick)
                        {
                            m_timeoutRequests.Add(request);
                        }
                    }

                    if (m_timeoutRequests.Count > 0)
                    {
                        for (int i = 0; i < m_timeoutRequests.Count; ++i)
                        {
                            PendingClientRequest timeoutRequest = m_timeoutRequests[i];
                            m_requests.Remove(timeoutRequest.TaskInfo.TaskId);
                            OnClientRequestTimeout(timeoutRequest);
                        }
                        m_timeoutRequests.Clear();
                    }
                }

                m_nextTimeoutCheck = m_tick + m_timeoutTicks / 4;
            }

            int batchSize = GameConstants.TaskEngineBatchSize;

            while (batchSize > 0 && m_activeTasks.Count > 0)
            {
                if (m_continueIteration < 0)
                {
                    m_continueIteration = m_activeTasks.Count - 1;
                }

                TaskBase activeTask = m_activeTasks[m_continueIteration];
                if (activeTask.TaskInfo.State == TaskState.Active)
                {
                    activeTask.Tick();
                }

                if (activeTask.TaskInfo.State != TaskState.Active)
                {
                    m_activeTasks.RemoveAt(m_continueIteration);
                    HandleActiveTaskRemoved(activeTask.TaskInfo);
                }

                m_continueIteration--;
                batchSize--;
            }

            m_tick++;
        }
        private void RaiseClientRequest(TaskInfo taskInfo)
        {
            PendingClientRequest pendingRequest = new PendingClientRequest(m_tick + m_timeoutTicks, taskInfo);

            m_requests.Add(taskInfo.TaskId, pendingRequest);

            if (ClientRequest != null)
            {
                ClientRequest(new ClientRequest(taskInfo.TaskId, taskInfo.PlayerIndex, taskInfo.Cmd));
            }
        }
Beispiel #3
0
        public void Write(PendingClientRequest pendingClientRequest)
        {
            if (pendingClientRequest == null)
            {
                throw new ArgumentNullException(nameof(pendingClientRequest));
            }

            if (!_pendingRequests.TryAdd(pendingClientRequest.Request.MetaData.RequestId, pendingClientRequest))
            {
                throw new InvalidOperationException("Another request with the same request ID is already pending: " + pendingClientRequest.Request.MetaData.RequestId);
            }
        }
        public async ValueTask <PendingClientRequest> WriteAsync(ClientRequest clientRequest, CancellationToken cancellationToken)
        {
            if (clientRequest == null)
            {
                throw new ArgumentNullException(nameof(clientRequest));
            }

            var pendingClientRequest = new PendingClientRequest(
                Request: clientRequest,
                Response: new TaskCompletionSource <ClientResponse>(TaskCreationOptions.RunContinuationsAsynchronously)
                );

            await _channel.Writer.WriteAsync(pendingClientRequest, cancellationToken).ConfigureAwait(false);

            return(pendingClientRequest);
        }
 private void OnClientRequestTimeout(PendingClientRequest request)
 {
     request.TaskInfo.State      = TaskState.Completed;
     request.TaskInfo.StatusCode = TaskInfo.TaskFailed;
 }