public List <CoinSnapshotData> GetLatestSnapshots( int limit, List <string> coinCodes, out int totalMiningCount, out int totalOnlineCount) { InitOnece(); totalMiningCount = HostRoot.Current.ClientSet.MiningCount; totalOnlineCount = HostRoot.Current.ClientSet.OnlineCount; List <CoinSnapshotData> results = new List <CoinSnapshotData>(); DateTime rightTime = DateTime.Now; DateTime leftTime = rightTime.AddSeconds(-limit * 10 - 10); if (leftTime > HostRoot.Current.StartedOn) { lock (_locker) { results = _dataList.Where(a => a.Timestamp > leftTime && a.Timestamp <= rightTime).OrderByDescending(a => a.Timestamp).ToList(); } } else { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); results = col.Find( Query.And( Query.GT(nameof(CoinSnapshotData.Timestamp), leftTime), Query.LTE(nameof(CoinSnapshotData.Timestamp), rightTime))).OrderByDescending(a => a.Timestamp).ToList(); } } List <CoinSnapshotData> list = new List <CoinSnapshotData>(limit * coinCodes.Count); for (int i = 1; i <= limit; i++) { DateTime time = rightTime.AddSeconds(-10 * i - 10); DateTime time2 = rightTime.AddSeconds(-10 * i + 10); foreach (var coinCode in coinCodes) { var dataItem = results.FirstOrDefault(a => a.Timestamp > time && a.Timestamp <= time2 && a.CoinCode == coinCode); if (dataItem != null) { list.Add(dataItem); } else { list.Add(new CoinSnapshotData { Id = ObjectId.NewObjectId(), CoinCode = coinCode, MainCoinMiningCount = 0, MainCoinOnlineCount = 0, DualCoinMiningCount = 0, DualCoinOnlineCount = 0, ShareDelta = 0, Speed = 0, Timestamp = time2 }); } } } return(list); }
public DateTime GetMinTimestamp() { InitOnece(); DateTime t = DateTime.MinValue; using (LiteDatabase db = HostRoot.CreateReportDb()) { int minId = db.GetCollection <ClientCoinSnapshotData>().Min(a => a.Id).AsInt32; if (minId != 0) { var clientCoinSpeedData = db.GetCollection <ClientCoinSnapshotData>().FindById(minId); if (clientCoinSpeedData != null) { t = clientCoinSpeedData.Timestamp; } } } if (t == DateTime.MinValue) { lock (_locker) { if (_dataList.Count > 0) { return(_dataList.Min(a => a.Timestamp)); } } } return(t); }
internal ClientCoinSnapshotSet(IHostRoot root) { _root = root; Global.Access <Per10SecondEvent>( Guid.Parse("e093f476-e79d-45ba-b527-95ca71c3b737"), "周期性将内存中的CientCoinSpeedData列表刷到磁盘", LogEnum.Console, action: message => { InitOnece(); if (message.Seconds > 4 * 60) { throw new InvalidProgramException("内存中保留4分钟的数据,所以刷新周期不能大于4分钟"); } ClientCoinSnapshotData[] values = null; using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientCoinSnapshotData>(); lock (_locker) { // 将最近一个周期生成的数据刷入磁盘 DateTime time = message.Timestamp.AddSeconds(-message.Seconds); values = _dataList.Where(a => a.Timestamp > time).ToArray(); // 将4分钟之前的数据从内存中清除 time = message.Timestamp.AddMinutes(-4); List <ClientCoinSnapshotData> toRemoves = _dataList.Where(a => a.Timestamp < time).ToList(); foreach (var item in toRemoves) { _dataList.Remove(item); } } if (values.Length != 0) { col.Upsert(values); } Global.DebugLine("刷了" + values.Length + "条", ConsoleColor.Green); } }); Global.Access <Per2MinuteEvent>( Guid.Parse("033f4391-6b37-4232-abf4-c12117b4716b"), "周期性清除已经拍过快照的CientCoinSpeedData源数据", LogEnum.Console, action: message => { InitOnece(); DateTime timestamp = SnapshotTimestamp.GetSnapshotTimestamp(); if (timestamp == DateTime.MinValue) { Global.DebugLine("尚没有拍摄过快照,无需清除"); return; } using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientCoinSnapshotData>(); int r = col.Delete(Query.LT(nameof(ClientCoinSnapshotData.Timestamp), timestamp)); if (r > 0) { db.Shrink(); } } }); }
public static DateTime GetSnapshotTimestamp() { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <SnapshotTimestamp>(); SnapshotTimestamp entity = col.FindById(1); if (entity == null) { return(HostRoot.Current.ClientCoinSnapshotSet.GetMinTimestamp()); } return(entity.Timestamp); } }
private void Snapshot(List <ClientCoinSnapshotData> clientCoinSpeedList, DateTime timestamp) { InitOnece(); Dictionary <string, List <ClientCoinSnapshotData> > clientCoinSpeedDic = clientCoinSpeedList.GroupBy(a => a.CoinCode).ToDictionary(a => a.Key, a => a.ToList()); List <CoinSnapshotData> data = new List <CoinSnapshotData>(); lock (_locker) { foreach (var item in clientCoinSpeedDic) { Dictionary <Guid, ClientCoinSnapshotData> dic = new Dictionary <Guid, ClientCoinSnapshotData>(); foreach (var clientCoinSnapshotData in item.Value) { if (!dic.ContainsKey(clientCoinSnapshotData.ClientId)) { dic.Add(clientCoinSnapshotData.ClientId, clientCoinSnapshotData); } else { dic[clientCoinSnapshotData.ClientId] = clientCoinSnapshotData; } } long speed = dic.Values.Sum(a => a.Speed); int shareDelta = dic.Values.Sum(a => a.ShareDelta); CoinSnapshotData snapshotdData = new CoinSnapshotData { Id = ObjectId.NewObjectId(), CoinCode = item.Key, MainCoinMiningCount = _root.ClientSet.CountMainCoinMining(item.Key), MainCoinOnlineCount = _root.ClientSet.CountMainCoinOnline(item.Key), DualCoinMiningCount = _root.ClientSet.CountDualCoinMining(item.Key), DualCoinOnlineCount = _root.ClientSet.CountDualCoinOnline(item.Key), Timestamp = timestamp, ShareDelta = shareDelta, Speed = speed }; data.Add(snapshotdData); } _dataList.AddRange(data); DateTime time = timestamp.AddMinutes(-20); List <CoinSnapshotData> toRemoves = _dataList.Where(a => a.Timestamp < time).ToList(); foreach (var item in toRemoves) { _dataList.Remove(item); } } if (data.Count > 0) { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); col.Insert(data); } Global.Logger.InfoDebugLine("拍摄快照" + data.Count + "张,快照时间戳:" + timestamp.ToString("yyyy-MM-dd HH:mm:ss fff")); } }
private bool IsSnapshoted(DateTime leftTime, DateTime rightTime) { InitOnece(); if (leftTime > DateTime.Now.AddMinutes(-20)) { lock (_locker) { return(_dataList.Any(a => a.Timestamp > leftTime && a.Timestamp <= rightTime)); } } using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); return(col.Exists( Query.And( Query.GT(nameof(CoinSnapshotData.Timestamp), leftTime), Query.LTE(nameof(CoinSnapshotData.Timestamp), rightTime)))); } }
private void Init() { lock (_locker) { if (!_isInited) { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientData>(); DateTime time = DateTime.Now.AddMinutes(-20); foreach (var item in col.Find(Query.GT(nameof(ClientData.ModifiedOn), time))) { _dicById.Add(item.Id, item); } } _isInited = true; } } }
public static void SetSnapshotTimestamp(DateTime timestamp) { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <SnapshotTimestamp>(); SnapshotTimestamp entity = col.FindById(1); if (entity == null) { col.Insert(new SnapshotTimestamp { Id = 1, Timestamp = timestamp }); } else { entity.Timestamp = timestamp; col.Update(entity); } } }
public List <ClientCoinSnapshotData> GetClientCoinSnapshots(DateTime leftTime, DateTime rightTime) { InitOnece(); if (leftTime > DateTime.Now.AddMinutes(-4)) { lock (_locker) { return(_dataList.Where(a => a.Timestamp > leftTime && a.Timestamp <= rightTime).ToList()); } } else { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientCoinSnapshotData>(); return(col.Find( Query.And( Query.GT(nameof(ClientCoinSnapshotData.Timestamp), leftTime), Query.LTE(nameof(ClientCoinSnapshotData.Timestamp), rightTime))).ToList()); } } }
private void Init() { lock (_locker) { if (!_isInited) { using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientCoinSnapshotData>(); // 将最近4分钟的数据载入内存 DateTime now = DateTime.Now; foreach (var item in col.Find( Query.And( Query.GT(nameof(ClientCoinSnapshotData.Timestamp), now.AddMinutes(-4)), Query.LTE(nameof(ClientCoinSnapshotData.Timestamp), now)))) { _dataList.Add(item); } } _isInited = true; } } }
public ClientData LoadClient(Guid clientId) { InitOnece(); ClientData clientData = null; lock (_locker) { if (_dicById.TryGetValue(clientId, out clientData)) { return(clientData); } } using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientData>(); clientData = col.FindById(clientId); if (clientData != null) { Add(clientData); } return(clientData); } }
private void Init() { lock (_locker) { if (!_isInited) { // 将最近20分钟的快照载入内存 DateTime now = DateTime.Now; using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); col.EnsureIndex(nameof(CoinSnapshotData.Timestamp), unique: false); foreach (var item in col.Find( Query.And( Query.GT(nameof(CoinSnapshotData.Timestamp), now.AddMinutes(-20)), Query.LTE(nameof(CoinSnapshotData.Timestamp), now)))) { _dataList.Add(item); } } Write.DevDebug("将最近20分钟的快照载入内存"); _isInited = true; } } }
internal ClientSet(IHostRoot root) { _root = root; Global.Access <Per10SecondEvent>( Guid.Parse("ea795e07-7f4b-4284-aa72-aa00c17c89d8"), "周期性将内存中的ClientData列表刷入磁盘", LogEnum.Console, action: message => { InitOnece(); lock (_locker) { DateTime time = message.Timestamp.AddMinutes(-20); List <Guid> toRemoves = _dicById.Where(a => a.Value.ModifiedOn < time).Select(a => a.Key).ToList(); foreach (var clientId in toRemoves) { _dicById.Remove(clientId); } using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <ClientData>(); col.Upsert(_dicById.Values); } } }); }
/// <summary> /// /// </summary> private void Snapshot(DateTime now) { InitOnece(); try { int onlineCount = 0; int miningCount = 0; Dictionary <string, CoinSnapshotData> dicByCoinCode = new Dictionary <string, CoinSnapshotData>(); foreach (var clientData in _root.ClientSet.AsEnumerable()) { if (HostRoot.Instance.HostConfig.IsPull) { if (clientData.ModifiedOn.AddSeconds(15) < now) { continue; } } else { if (clientData.ModifiedOn.AddSeconds(130) < now) { continue; } } onlineCount++; if (string.IsNullOrEmpty(clientData.MainCoinCode)) { continue; } if (!dicByCoinCode.TryGetValue(clientData.MainCoinCode, out CoinSnapshotData mainCoinSnapshotData)) { mainCoinSnapshotData = new CoinSnapshotData() { Timestamp = now, CoinCode = clientData.MainCoinCode }; dicByCoinCode.Add(clientData.MainCoinCode, mainCoinSnapshotData); } if (clientData.IsMining) { miningCount++; mainCoinSnapshotData.MainCoinMiningCount += 1; mainCoinSnapshotData.Speed += clientData.MainCoinSpeed; mainCoinSnapshotData.ShareDelta += clientData.GetMainCoinShareDelta(HostRoot.Instance.HostConfig.IsPull); mainCoinSnapshotData.RejectShareDelta += clientData.GetMainCoinRejectShareDelta(HostRoot.Instance.HostConfig.IsPull); } mainCoinSnapshotData.MainCoinOnlineCount += 1; if (!string.IsNullOrEmpty(clientData.DualCoinCode) && clientData.IsDualCoinEnabled) { if (!dicByCoinCode.TryGetValue(clientData.DualCoinCode, out CoinSnapshotData dualCoinSnapshotData)) { dualCoinSnapshotData = new CoinSnapshotData() { Timestamp = now, CoinCode = clientData.DualCoinCode }; dicByCoinCode.Add(clientData.DualCoinCode, dualCoinSnapshotData); } if (clientData.IsMining) { dualCoinSnapshotData.DualCoinMiningCount += 1; dualCoinSnapshotData.Speed += clientData.DualCoinSpeed; dualCoinSnapshotData.ShareDelta += clientData.GetDualCoinShareDelta(HostRoot.Instance.HostConfig.IsPull); dualCoinSnapshotData.RejectShareDelta += clientData.GetDualCoinRejectShareDelta(HostRoot.Instance.HostConfig.IsPull); } dualCoinSnapshotData.DualCoinOnlineCount += 1; } } HostRoot.ClientCount.Update(onlineCount, miningCount); if (dicByCoinCode.Count > 0) { _dataList.AddRange(dicByCoinCode.Values); using (LiteDatabase db = HostRoot.CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); col.Insert(dicByCoinCode.Values); } Write.DevDebug("拍摄快照" + dicByCoinCode.Count + "张,快照时间戳:" + now.ToString("yyyy-MM-dd HH:mm:ss fff")); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }