Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 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();
             }
         }
     });
 }
Пример #4
0
 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);
     }
 }
Пример #5
0
        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"));
            }
        }
Пример #6
0
 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))));
     }
 }
Пример #7
0
 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;
         }
     }
 }
Пример #8
0
 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);
         }
     }
 }
Пример #9
0
 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());
         }
     }
 }
Пример #10
0
 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;
         }
     }
 }
Пример #11
0
        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);
            }
        }
Пример #12
0
 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;
         }
     }
 }
Пример #13
0
 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);
             }
         }
     });
 }
Пример #14
0
        /// <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);
            }
        }