From bf22309fe52ae8af637148993be778422468d544 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Sun, 16 Apr 2023 19:41:54 +0800 Subject: [PATCH] opt. for performance --- lib/data/model/server/cpu_status.dart | 4 +- lib/data/model/server/server.dart | 4 +- lib/data/provider/server.dart | 127 +++++++++++++------------- lib/data/store/setting.dart | 2 +- lib/view/page/server/tab.dart | 2 +- lib/view/page/sftp/view.dart | 2 +- 6 files changed, 72 insertions(+), 69 deletions(-) diff --git a/lib/data/model/server/cpu_status.dart b/lib/data/model/server/cpu_status.dart index f6772541..82cb8f9e 100644 --- a/lib/data/model/server/cpu_status.dart +++ b/lib/data/model/server/cpu_status.dart @@ -114,10 +114,8 @@ List parseCPU(String raw) { final cpuTempReg = RegExp(r'(x86_pkg_temp|cpu_thermal)'); -String parseCPUTemp(List segments) { +String parseCPUTemp(String type, String value) { const noMatch = "/sys/class/thermal/thermal_zone*/type"; - final type = segments[0]; - final value = segments[1]; // Not support to get CPU temperature if (value.contains(noMatch) || type.contains(noMatch) || diff --git a/lib/data/model/server/server.dart b/lib/data/model/server/server.dart index 068f2b13..cb7df5dc 100644 --- a/lib/data/model/server/server.dart +++ b/lib/data/model/server/server.dart @@ -6,9 +6,9 @@ class Server { ServerPrivateInfo spi; ServerStatus status; SSHClient? client; - ServerState cs; + ServerState state; - Server(this.spi, this.status, this.client, this.cs); + Server(this.spi, this.status, this.client, this.state); } enum ServerState { diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 6dc000f9..985af7e7 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; +import 'package:toolbox/data/model/server/server_status.dart'; import '../../core/extension/uint8list.dart'; import '../../core/provider_base.dart'; @@ -49,7 +50,7 @@ class ServerProvider extends BusyProvider { } await Future.wait(_servers.map((s) async { if (onlyFailed) { - if (s.cs != ServerState.failed) return; + if (s.state != ServerState.failed) return; _limiter.resetTryTimes(s.spi.id); } await _getData(s.spi); @@ -75,7 +76,7 @@ class ServerProvider extends BusyProvider { void setDisconnected() { for (var i = 0; i < _servers.length; i++) { - _servers[i].cs = ServerState.disconnected; + _servers[i].state = ServerState.disconnected; } _limiter.clear(); notifyListeners(); @@ -135,14 +136,14 @@ class ServerProvider extends BusyProvider { Future _getData(ServerPrivateInfo spi) async { final sid = spi.id; final s = getServer(sid); - final state = s.cs; + final state = s.state; if (state.shouldConnect) { if (!_limiter.shouldTry(sid)) { - s.cs = ServerState.failed; + s.state = ServerState.failed; notifyListeners(); return; } - s.cs = ServerState.connecting; + s.state = ServerState.connecting; notifyListeners(); try { @@ -154,7 +155,7 @@ class ServerProvider extends BusyProvider { _logger.info('Connected to [$sid] in $spentTime ms.'); // after connected - s.cs = ServerState.connected; + s.state = ServerState.connected; final writeResult = await s.client!.run(installShellCmd).string; // if write failed @@ -163,8 +164,8 @@ class ServerProvider extends BusyProvider { } _limiter.resetTryTimes(sid); } catch (e) { - s.cs = ServerState.failed; - s.status.failedInfo = '$e'; + s.state = ServerState.failed; + s.status.failedInfo = e.toString(); _logger.warning(e); } finally { notifyListeners(); @@ -176,7 +177,7 @@ class ServerProvider extends BusyProvider { final raw = await s.client!.run("sh $shellPath").string; final segments = raw.split(seperator).map((e) => e.trim()).toList(); if (raw.isEmpty || segments.length == 1) { - s.cs = ServerState.failed; + s.state = ServerState.failed; if (s.status.failedInfo == null || s.status.failedInfo!.isEmpty) { s.status.failedInfo = 'Seperate segments failed, raw:\n$raw'; } @@ -184,18 +185,14 @@ class ServerProvider extends BusyProvider { return; } // remove first empty segment + // for `export xxx` in shell script segments.removeAt(0); try { - _getCPU(sid, segments[2], segments[7], segments[8]); - _getMem(sid, segments[6]); - _getSysVer(sid, segments[1]); - _getUpTime(sid, segments[3]); - _getDisk(sid, segments[5]); - _getTcp(sid, segments[4]); - _getNetSpeed(sid, segments[0]); + final req = ServerStatusUpdateReq(s.status, segments); + s.status = await compute(_getStatus, req); } catch (e) { - s.cs = ServerState.failed; + s.state = ServerState.failed; s.status.failedInfo = e.toString(); _logger.warning(e); rethrow; @@ -204,50 +201,6 @@ class ServerProvider extends BusyProvider { } } - Future _getNetSpeed(String id, String raw) async { - final net = await compute(parseNetSpeed, raw); - getServer(id).status.netSpeed.update(net); - } - - void _getSysVer(String id, String raw) { - final s = raw.split('='); - if (s.length == 2) { - final ver = s[1].replaceAll('"', '').replaceFirst('\n', ''); - getServer(id).status.sysVer = ver; - } - } - - Future _getCPU( - String id, String raw, String tempType, String tempValue) async { - final cpus = await compute(parseCPU, raw); - final temp = await compute(parseCPUTemp, [tempType, tempValue]); - - if (cpus.isNotEmpty) { - getServer(id).status.cpu.update(cpus, temp); - } - } - - void _getUpTime(String id, String raw) { - getServer(id).status.uptime = raw.split('up ')[1].split(', ')[0]; - } - - Future _getTcp(String id, String raw) async { - final status = await compute(parseTcp, raw); - if (status != null) { - getServer(id).status.tcp = status; - } - } - - Future _getDisk(String id, String raw) async { - getServer(id).status.disk = await compute(parseDisk, raw); - } - - Future _getMem(String id, String raw) async { - final s = getServer(id); - s.status.mem = await compute(parseMem, raw); - s.status.swap = await compute(parseSwap, raw); - } - Future runSnippet(String id, Snippet snippet) async { final client = getServer(id).client; if (client == null) { @@ -281,3 +234,55 @@ class _TryLimiter { _triedTimes.clear(); } } + +class ServerStatusUpdateReq { + final ServerStatus ss; + final List segments; + + const ServerStatusUpdateReq(this.ss, this.segments); +} + +Future _getStatus(ServerStatusUpdateReq req) async { + final net = parseNetSpeed(req.segments[0]); + req.ss.netSpeed.update(net); + final sys = parseSysVer(req.segments[1]); + if (sys != null) { + req.ss.sysVer = sys; + } + final cpus = parseCPU(req.segments[2]); + final cpuTemp = parseCPUTemp(req.segments[7], req.segments[8]); + req.ss.cpu.update(cpus, cpuTemp); + final tcp = parseTcp(req.segments[4]); + if (tcp != null) { + req.ss.tcp = tcp; + } + req.ss.disk = parseDisk(req.segments[5]); + req.ss.mem = parseMem(req.segments[6]); + final uptime = parseUpTime(req.segments[3]); + if (uptime != null) { + req.ss.uptime = uptime; + } + req.ss.swap = parseSwap(req.segments[6]); + return req.ss; +} + +// raw: +// 19:39:15 up 61 days, 18:16, 1 user, load average: 0.00, 0.00, 0.00 +String? parseUpTime(String raw) { + final splitedUp = raw.split('up '); + if (splitedUp.length == 2) { + final splitedComma = splitedUp[1].split(', '); + if (splitedComma.length >= 2) { + return splitedComma[0]; + } + } + return null; +} + +String? parseSysVer(String raw) { + final s = raw.split('='); + if (s.length == 2) { + return s[1].replaceAll('"', '').replaceFirst('\n', ''); + } + return null; +} diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 8afa0ed4..8bc321ce 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -28,7 +28,7 @@ class SettingStore extends PersistentStore { /// Max retry count when connect to server StoreProperty get maxRetryCount => - property('maxRetryCount', defaultValue: 7); + property('maxRetryCount', defaultValue: 2); /// Night mode: 0 -> auto, 1 -> light, 2 -> dark StoreProperty get themeMode => property('themeMode', defaultValue: 0); diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 4b60a51f..330f9739 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -115,7 +115,7 @@ class _ServerPageState extends State .go(context), child: Padding( padding: const EdgeInsets.all(13), - child: _buildRealServerCard(si.status, si.spi.name, si.cs, si.spi), + child: _buildRealServerCard(si.status, si.spi.name, si.state, si.spi), ), onTap: () => AppRoute(ServerDetailPage(si.spi.id), 'server detail page') .go(context), diff --git a/lib/view/page/sftp/view.dart b/lib/view/page/sftp/view.dart index 0b667b80..216f8e7e 100644 --- a/lib/view/page/sftp/view.dart +++ b/lib/view/page/sftp/view.dart @@ -177,7 +177,7 @@ class _SFTPPageState extends State { ); Widget _buildFileView() { - if (_client == null || _si?.cs != ServerState.connected) { + if (_client == null || _si?.state != ServerState.connected) { return centerCircleLoading; }