From 026d203608f1b5f375397a8d53ed15c252efc3b3 Mon Sep 17 00:00:00 2001 From: Junyuan Feng Date: Wed, 2 Feb 2022 13:23:54 +0800 Subject: [PATCH] Improve efficiency of data fetching --- lib/data/model/server/server.dart | 3 +- lib/data/provider/server.dart | 115 ++++++++++++++---------------- lib/data/res/build_data.dart | 9 ++- lib/view/page/home.dart | 9 ++- lib/view/page/ping.dart | 81 ++++++++++----------- lib/view/page/server/tab.dart | 6 +- lib/view/page/setting.dart | 1 - make.dart | 10 +++ 8 files changed, 121 insertions(+), 113 deletions(-) diff --git a/lib/data/model/server/server.dart b/lib/data/model/server/server.dart index 41e0c656..89cecffa 100644 --- a/lib/data/model/server/server.dart +++ b/lib/data/model/server/server.dart @@ -9,5 +9,6 @@ class ServerInfo { SSHClient? client; ServerConnectionState connectionState; - ServerInfo(this.info, this.status, this.client, this.connectionState); + ServerInfo( + this.info, this.status, this.client, this.connectionState); } diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index b6c80a19..00309032 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -85,16 +85,14 @@ class ServerProvider extends BusyProvider { identities: await compute(loadIndentity, key.privateKey)); } - Future refreshData({int? idx}) async { - if (idx != null) { - _getData(idx); + Future refreshData({ServerPrivateInfo? spi}) async { + if (spi != null) { + _getData(spi); return; } try { await Future.wait(_servers.map((s) async { - final idx = _servers.indexOf(s); - if (idx == -1) return; - await _getData(idx); + await _getData(s.info); })); } catch (e) { if (e is! RangeError) { @@ -120,11 +118,17 @@ class ServerProvider extends BusyProvider { } } - void addServer(ServerPrivateInfo info) { - _servers.add(genInfo(info)); - locator().put(info); + void setDisconnected() { + for (var i = 0; i < _servers.length; i++) { + _servers[i].connectionState = ServerConnectionState.disconnected; + } + } + + void addServer(ServerPrivateInfo spi) { + _servers.add(genInfo(spi)); + locator().put(spi); notifyListeners(); - refreshData(idx: _servers.length - 1); + refreshData(spi: spi); } void delServer(ServerPrivateInfo info) { @@ -136,17 +140,17 @@ class ServerProvider extends BusyProvider { } Future updateServer( - ServerPrivateInfo old, ServerPrivateInfo newInfo) async { + ServerPrivateInfo old, ServerPrivateInfo newSpi) async { final idx = _servers.indexWhere((e) => e.info == old); - _servers[idx].info = newInfo; - _servers[idx].client = await genClient(newInfo); - locator().update(old, newInfo); + _servers[idx].info = newSpi; + _servers[idx].client = await genClient(newSpi); + locator().update(old, newSpi); notifyListeners(); - refreshData(idx: idx); + refreshData(spi: newSpi); } - Future _getData(int idx) async { - final info = _servers[idx].info; + Future _getData(ServerPrivateInfo spi) async { + final idx = _servers.indexWhere((element) => element.info == spi); final state = _servers[idx].connectionState; if (_servers[idx].client == null || state == ServerConnectionState.failed || @@ -155,10 +159,10 @@ class ServerProvider extends BusyProvider { notifyListeners(); final time1 = DateTime.now(); try { - _servers[idx].client = await genClient(info); + _servers[idx].client = await genClient(spi); final time2 = DateTime.now(); logger.info( - 'Connected to [${info.name}] in [${time2.difference(time1).toString()}].'); + 'Connected to [${spi.name}] in [${time2.difference(time1).toString()}].'); _servers[idx].connectionState = ServerConnectionState.connected; notifyListeners(); } catch (e) { @@ -168,15 +172,19 @@ class ServerProvider extends BusyProvider { logger.warning(e); } } + final si = _servers[idx]; try { - if (_servers[idx].client == null) return; - _getCPU(_servers[idx]); - _getMem(_servers[idx]); - _getSysVer(_servers[idx]); - _getUpTime(_servers[idx]); - _getDisk(_servers[idx]); - _getTcp(_servers[idx]); - _getNetSpeed(_servers[idx]); + if (si.client == null) return; + final raw = utf8.decode(await si.client!.run( + r"cat /proc/net/dev && date +%s && echo 'A====A' && cat /etc/os-release | grep PRETTY_NAME && echo 'A====A' && cat /proc/stat | grep cpu && echo 'A====A' && paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/' && echo 'A====A' && uptime && echo 'A====A' && cat /proc/net/snmp && echo 'A====A' && df -h && echo 'A====A' && free -m")); + final lines = raw.split('A====A').map((e) => e.trim()).toList(); + _getCPU(spi, lines[2], lines[3]); + _getMem(spi, lines[7]); + _getSysVer(spi, lines[1]); + _getUpTime(spi, lines[4]); + _getDisk(spi, lines[6]); + _getTcp(spi, lines[5]); + _getNetSpeed(spi, lines[0]); } catch (e) { _servers[idx].connectionState = ServerConnectionState.failed; servers[idx].status.failedInfo = e.toString(); @@ -191,14 +199,12 @@ class ServerProvider extends BusyProvider { /// lo: 45929941 269112 0 0 0 0 0 0 45929941 269112 0 0 0 0 0 0 /// eth0: 48481023 505772 0 0 0 0 0 0 36002262 202307 0 0 0 0 0 0 /// 1635752901 - Future _getNetSpeed(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final raw = utf8.decode(await client.run('cat /proc/net/dev && date +%s')); + Future _getNetSpeed(ServerPrivateInfo spi, String raw) async { + final info = _servers.firstWhere((e) => e.info == spi); final split = raw.split('\n'); final deviceCount = split.length - 3; if (deviceCount < 1) return; - final time = int.parse(split[split.length - 2]); + final time = int.parse(split[split.length - 1]); final results = []; for (int idx = 2; idx < deviceCount; idx++) { final data = split[idx].trim().split(':'); @@ -213,11 +219,8 @@ class ServerProvider extends BusyProvider { notifyListeners(); } - Future _getSysVer(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final raw = - utf8.decode(await client.run('cat /etc/os-release | grep PRETTY_NAME')); + Future _getSysVer(ServerPrivateInfo spi, String raw) async { + final info = _servers.firstWhere((e) => e.info == spi); final s = raw.split('='); if (s.length == 2) { info.status.sysVer = s[1].replaceAll('"', '').replaceFirst('\n', ''); @@ -238,12 +241,8 @@ class ServerProvider extends BusyProvider { return ''; } - Future _getCPU(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final raw = utf8.decode(await client.run("cat /proc/stat | grep cpu")); - final temp = utf8.decode(await client.run( - r"paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/'")); + Future _getCPU(ServerPrivateInfo spi, String raw, String temp) async { + final info = _servers.firstWhere((e) => e.info == spi); final List cpus = []; for (var item in raw.split('\n')) { @@ -270,18 +269,14 @@ class ServerProvider extends BusyProvider { notifyListeners(); } - Future _getUpTime(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final raw = utf8.decode(await client.run('uptime')); - info.status.uptime = raw.split('up ')[1].split(', ')[0]; + Future _getUpTime(ServerPrivateInfo spi, String raw) async { + _servers.firstWhere((e) => e.info == spi).status.uptime = + raw.split('up ')[1].split(', ')[0]; notifyListeners(); } - Future _getTcp(ServerInfo info) async { - final sidx = _servers.indexOf(info); - final client = _servers[sidx].client!; - final raw = utf8.decode(await client.run('cat /proc/net/snmp')); + Future _getTcp(ServerPrivateInfo spi, String raw) async { + final info = _servers.firstWhere((e) => e.info == spi); final lines = raw.split('\n'); final idx = lines.lastWhere((element) => element.startsWith('Tcp:'), orElse: () => ''); @@ -294,12 +289,10 @@ class ServerProvider extends BusyProvider { notifyListeners(); } - Future _getDisk(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final disk = utf8.decode(await client.run('df -h')); + Future _getDisk(ServerPrivateInfo spi, String raw) async { + final info = _servers.firstWhere((e) => e.info == spi); final list = []; - final items = disk.split('\n'); + final items = raw.split('\n'); for (var item in items) { if (items.indexOf(item) == 0 || item.isEmpty) { continue; @@ -312,11 +305,9 @@ class ServerProvider extends BusyProvider { notifyListeners(); } - Future _getMem(ServerInfo info) async { - final idx = _servers.indexOf(info); - final client = _servers[idx].client!; - final mem = utf8.decode(await client.run('free -m')); - for (var item in mem.split('\n')) { + Future _getMem(ServerPrivateInfo spi, String raw) async { + final info = _servers.firstWhere((e) => e.info == spi); + for (var item in raw.split('\n')) { if (item.contains('Mem:')) { final split = item.replaceFirst('Mem:', '').split(' '); split.removeWhere((e) => e == ''); diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index c0119f5e..35f79695 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,8 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 86; - static const String engine = - "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (5 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; - static const String buildAt = "2022-01-19 16:54:18.470020"; - static const int modifications = 0; + static const int build = 87; + static const String engine = "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (7 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; + static const String buildAt = "2022-02-02 13:20:22.346643"; + static const int modifications = 8; } diff --git a/lib/view/page/home.dart b/lib/view/page/home.dart index 118b009d..4ccc194b 100644 --- a/lib/view/page/home.dart +++ b/lib/view/page/home.dart @@ -65,6 +65,7 @@ class _MyHomePageState extends State void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); if (state == AppLifecycleState.paused) { + _serverProvider.setDisconnected(); _serverProvider.stopAutoRefresh(); } if (state == AppLifecycleState.resumed) { @@ -90,9 +91,11 @@ class _MyHomePageState extends State ), ), drawer: _buildDrawer(), - body: TabBarView( - controller: _tabController, - children: const [ServerPage(), ConvertPage(), PingPage()]), + body: TabBarView(controller: _tabController, children: [ + ServerPage(_tabController), + const ConvertPage(), + const PingPage() + ]), ); } diff --git a/lib/view/page/ping.dart b/lib/view/page/ping.dart index 243ce774..8ed5f3e2 100644 --- a/lib/view/page/ping.dart +++ b/lib/view/page/ping.dart @@ -48,7 +48,8 @@ class _PingPageState extends State buildInput(context, _textEditingController, maxLines: 1, hint: 'Type here.'), _buildControl(), - buildInput(context, _textEditingControllerResult, hint: 'Result here.'), + buildInput(context, _textEditingControllerResult, + hint: 'Result here.'), ])), onTap: () => FocusScope.of(context).requestFocus(FocusNode()), ), @@ -73,46 +74,46 @@ class _PingPageState extends State child: InkWell( onTap: () => FocusScope.of(context).unfocus(), child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - TextButton( - style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(primaryColor)), - child: Row( - children: const [ - Icon(Icons.stop), - SizedBox( - width: 7, - ), - Text('Stop') - ], + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + TextButton( + style: ButtonStyle( + foregroundColor: MaterialStateProperty.all(primaryColor)), + child: Row( + children: const [ + Icon(Icons.stop), + SizedBox( + width: 7, + ), + Text('Stop') + ], + ), + onPressed: () { + if (_ping != null) _ping!.stop(); + }, ), - onPressed: () { - if (_ping != null) _ping!.stop(); - }, - ), - TextButton( - style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(primaryColor)), - child: Row( - children: const [ - Icon(Icons.play_arrow), - SizedBox( - width: 7, - ), - Text('Start') - ], - ), - onPressed: () { - try { - doPing(); - } catch (e) { - showSnackBar(context, Text('Error: \n$e')); - } - }, - ) - ], - ), + TextButton( + style: ButtonStyle( + foregroundColor: MaterialStateProperty.all(primaryColor)), + child: Row( + children: const [ + Icon(Icons.play_arrow), + SizedBox( + width: 7, + ), + Text('Start') + ], + ), + onPressed: () { + try { + doPing(); + } catch (e) { + showSnackBar(context, Text('Error: \n$e')); + } + }, + ) + ], + ), ), ), ); diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index cd31520e..9d08872f 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -17,7 +17,8 @@ import 'package:toolbox/view/page/server/detail.dart'; import 'package:toolbox/view/page/server/edit.dart'; class ServerPage extends StatefulWidget { - const ServerPage({Key? key}) : super(key: key); + final TabController tabController; + const ServerPage(this.tabController, {Key? key}) : super(key: key); @override _ServerPageState createState() => _ServerPageState(); @@ -45,6 +46,9 @@ class _ServerPageState extends State _media = MediaQuery.of(context); _theme = Theme.of(context); _primaryColor = primaryColor; + if (widget.tabController.index == 0) { + FocusScope.of(context).unfocus(); + } } @override diff --git a/lib/view/page/setting.dart b/lib/view/page/setting.dart index a53af869..381a56a3 100644 --- a/lib/view/page/setting.dart +++ b/lib/view/page/setting.dart @@ -194,7 +194,6 @@ class _SettingPageState extends State { child: Text( tabs[_launchPageIdx], style: textStyle, - textScaleFactor: 1.0, textAlign: TextAlign.right, ), ), diff --git a/make.dart b/make.dart index 4a635020..25a6c02f 100755 --- a/make.dart +++ b/make.dart @@ -67,6 +67,15 @@ Future updateBuildData() async { await writeStaicConfigFile(data, 'BuildData', path); } +void dartFormat() { + final result = Process.runSync('dart', ['format', './*.dart']); + print(result.stdout); + if (result.exitCode != 0) { + print(result.stderr); + exit(1); + } +} + void flutterRun(String? mode) { Process.start('flutter', ['run', mode == null ? '' : '--$mode'], mode: ProcessStartMode.inheritStdio, runInShell: true); @@ -126,6 +135,7 @@ void main(List args) async { case 'build': if (args.length > 1) { await updateBuildData(); + dartFormat(); if (args[1] == 'android' || args[1] == 'harmony') { return flutterBuildAndroid(); } else if (args[1] == 'ios') {