using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using ZeroLevel.Services.Pools; namespace ZeroLevel.Network { internal sealed class RequestBuffer { private ConcurrentDictionary _requests = new ConcurrentDictionary(); private static ObjectPool _ri_pool = new ObjectPool(() => new RequestInfo()); public void RegisterForFrame(int identity, Action callback, Action fail = null) { var ri = _ri_pool.Allocate(); ri.Reset(callback, fail); _requests[identity] = ri; } public void Fail(long frameId, string message) { RequestInfo ri; if (_requests.TryRemove(frameId, out ri)) { ri.Fail(message); _ri_pool.Free(ri); } } public void Success(long frameId, byte[] data) { RequestInfo ri; if (_requests.TryRemove(frameId, out ri)) { ri.Success(data); _ri_pool.Free(ri); } } public void StartSend(long frameId) { RequestInfo ri; if (_requests.TryGetValue(frameId, out ri)) { ri.StartSend(); } } public void Timeout(List frameIds) { RequestInfo ri; for (int i = 0; i < frameIds.Count; i++) { if (_requests.TryRemove(frameIds[i], out ri)) { _ri_pool.Free(ri); } } } public void TestForTimeouts() { var now_ticks = DateTime.UtcNow.Ticks; var to_remove = new List(); foreach (var pair in _requests) { if (pair.Value.Sended == false) continue; var diff = now_ticks - pair.Value.Timestamp; if (diff > BaseSocket.MAX_REQUEST_TIME_TICKS) { to_remove.Add(pair.Key); } } Timeout(to_remove); } } }