/// <summary> /// 这里挺绕,逻辑是父类通过回调函数的参数声明一个接收矿工列表的方法,然后由 /// 子类调用该基类方法时传入矿工列表,从而父类收到了来自子类的矿工列表。因为 /// 该基类有两个子类,一个子类的数据源是redis一个子类的数据源是litedb。 /// </summary> /// <param name="isPull">内网群控传true,外网群控传false</param> /// <param name="getDatas"></param> public ClientDataSetBase(bool isPull, Action <Action <IEnumerable <ClientData> > > getDatas) { _isPull = isPull; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); getDatas(clientDatas => { foreach (var clientData in clientDatas) { _dicByObjectId[clientData.Id] = clientData; _dicByClientId[clientData.ClientId] = clientData; } InitedOn = DateTime.Now; IsReadied = true; stopwatch.Stop(); NTMinerConsole.UserLine($"矿机集就绪,耗时 {stopwatch.GetElapsedSeconds().ToString("f2")} 秒", isPull ? MessageType.Debug : MessageType.Ok); VirtualRoot.RaiseEvent(new ClientSetInitedEvent()); }); if (!isPull) { VirtualRoot.BuildEventPath <Per1MinuteEvent>("周期清理不活跃的缓存数据", LogEnum.None, typeof(ClientDataSetBase), PathPriority.Normal, message => { DateTime time = message.BornOn.AddMinutes(-10); string[] loginNameToRemoves = _clientDatasByLoginName.Where(a => a.Value.LastAccessOn <= time).Select(a => a.Key).ToArray(); foreach (var loginName in loginNameToRemoves) { _clientDatasByLoginName.TryRemove(loginName, out _); } }); } }
public MinerClientConsoleViewModel() { if (ClientAppType.IsMinerStudio) { VirtualRoot.BuildEventPath <MinerClientSelectionChangedEvent>("刷新矿机控制台输出", LogEnum.DevConsole, path: message => { bool isChanged = true; if (message.MinerClientVm != null && this._minerClientVm != null && this._minerClientVm.ClientId == message.MinerClientVm.ClientId) { isChanged = false; } LatestTimestamp = Timestamp.UnixBaseTime; if (isChanged) { lock (_locker) { _outLines.Clear(); try { Console.Clear(); } catch { } this._minerClientVm = message.MinerClientVm; } SendGetConsoleOutLinesMqMessage(isFast: true); } }, this.GetType()); VirtualRoot.BuildEventPath <ClientConsoleOutLinesEvent>("将收到的挖矿端控制台消息输出到输出窗口", LogEnum.DevConsole, path: message => { if (this._minerClientVm == null || this._minerClientVm.ClientId != message.ClientId || message.Data == null || message.Data.Count == 0) { return; } lock (_locker) { foreach (var item in message.Data) { _outLines.Add(item); NTMinerConsole.UserLine(item.Line, ConsoleColor.White, withPrefix: false); } // 因为客户端的时间可能不准所以不能使用客户端的时间 LatestTimestamp = DateTime.Now; } }, this.GetType()); VirtualRoot.BuildEventPath <Per5SecondEvent>("周期获取当前选中的那台矿机的控制台输出", LogEnum.DevConsole, path: message => { SendGetConsoleOutLinesMqMessage(isFast: false); }, this.GetType()); VirtualRoot.BuildEventPath <Per1SecondEvent>("客户端控制台输出倒计时秒表", LogEnum.None, path: message => { if (this._minerClientVm == null || this._latestTimestamp == Timestamp.UnixBaseTime) { return; } OnPropertyChanged(nameof(LatestTimeSpanText)); }, this.GetType()); } }
/// <summary> /// 这里挺绕,逻辑是父类通过回调函数的参数声明一个接收矿工列表的方法,然后由 /// 子类调用该基类方法时传入矿工列表,从而父类收到了来自子类的矿工列表。因为 /// 该基类有两个子类,一个子类的数据源是redis一个子类的数据源是litedb。 /// </summary> /// <param name="isPull">内网群控传true,外网群控传false</param> /// <param name="getDatas"></param> public ClientDataSetBase(bool isPull, Action <Action <IEnumerable <ClientData> > > getDatas) { _isPull = isPull; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); getDatas(clientDatas => { foreach (var clientData in clientDatas) { _dicByObjectId[clientData.Id] = clientData; _dicByClientId[clientData.ClientId] = clientData; } InitedOn = DateTime.Now; IsReadied = true; stopwatch.Stop(); NTMinerConsole.UserLine($"矿机集就绪,耗时 {stopwatch.GetElapsedSeconds().ToString("f2")} 秒", isPull ? MessageType.Debug : MessageType.Ok); VirtualRoot.RaiseEvent(new ClientSetInitedEvent()); }); }
/// <summary> /// /// </summary> private void Snapshot(DateTime now) { InitOnece(); try { var coinSnapshots = VirtualRoot.CreateCoinSnapshots(_isPull, now, _clientSet.AsEnumerable().ToArray(), out int onlineCount, out int miningCount); _clientSet.ClientCount.Update(onlineCount, miningCount); if (coinSnapshots.Count > 0) { _dataList.AddRange(coinSnapshots); using (LiteDatabase db = CreateReportDb()) { var col = db.GetCollection <CoinSnapshotData>(); col.Insert(coinSnapshots); } NTMinerConsole.UserLine("拍摄快照" + coinSnapshots.Count + "张,快照时间戳:" + now.ToString("yyyy-MM-dd HH:mm:ss fff"), _isPull ? MessageType.Debug : MessageType.Info); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
/// <summary> /// 这里挺绕,逻辑是由父类向子类传入一个接收一个矿工列表的方法,然后由子类调用该方法时传入矿工列表,从而父类收到了来自子类的矿工列表。 /// </summary> /// <param name="isPull"></param> /// <param name="getDatas"></param> public ClientDataSetBase(bool isPull, Action <Action <IEnumerable <ClientData> > > getDatas) { _isPull = isPull; getDatas(datas => { InitedOn = DateTime.Now; IsReadied = true; foreach (var item in datas) { if (!_dicByObjectId.ContainsKey(item.Id)) { _dicByObjectId.Add(item.Id, item); } if (!_dicByClientId.ContainsKey(item.ClientId)) { _dicByClientId.Add(item.ClientId, item); } } NTMinerConsole.UserLine("矿机集就绪", isPull ? MessageType.Debug : MessageType.Ok); VirtualRoot.RaiseEvent(new ClientSetInitedEvent()); }); }
private void Init() { lock (_locker) { if (!_isInited) { // 将最近20分钟的快照载入内存 DateTime now = DateTime.Now; using (LiteDatabase db = 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); } } NTMinerConsole.UserLine("将最近20分钟的快照载入内存", _isPull ? MessageType.Debug : MessageType.Info); _isInited = true; } } }