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