mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 15:24:35 +01:00
opt. for performance
This commit is contained in:
@@ -114,10 +114,8 @@ List<OneTimeCpuStatus> parseCPU(String raw) {
|
|||||||
|
|
||||||
final cpuTempReg = RegExp(r'(x86_pkg_temp|cpu_thermal)');
|
final cpuTempReg = RegExp(r'(x86_pkg_temp|cpu_thermal)');
|
||||||
|
|
||||||
String parseCPUTemp(List<String> segments) {
|
String parseCPUTemp(String type, String value) {
|
||||||
const noMatch = "/sys/class/thermal/thermal_zone*/type";
|
const noMatch = "/sys/class/thermal/thermal_zone*/type";
|
||||||
final type = segments[0];
|
|
||||||
final value = segments[1];
|
|
||||||
// Not support to get CPU temperature
|
// Not support to get CPU temperature
|
||||||
if (value.contains(noMatch) ||
|
if (value.contains(noMatch) ||
|
||||||
type.contains(noMatch) ||
|
type.contains(noMatch) ||
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class Server {
|
|||||||
ServerPrivateInfo spi;
|
ServerPrivateInfo spi;
|
||||||
ServerStatus status;
|
ServerStatus status;
|
||||||
SSHClient? client;
|
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 {
|
enum ServerState {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:toolbox/data/model/server/server_status.dart';
|
||||||
|
|
||||||
import '../../core/extension/uint8list.dart';
|
import '../../core/extension/uint8list.dart';
|
||||||
import '../../core/provider_base.dart';
|
import '../../core/provider_base.dart';
|
||||||
@@ -49,7 +50,7 @@ class ServerProvider extends BusyProvider {
|
|||||||
}
|
}
|
||||||
await Future.wait(_servers.map((s) async {
|
await Future.wait(_servers.map((s) async {
|
||||||
if (onlyFailed) {
|
if (onlyFailed) {
|
||||||
if (s.cs != ServerState.failed) return;
|
if (s.state != ServerState.failed) return;
|
||||||
_limiter.resetTryTimes(s.spi.id);
|
_limiter.resetTryTimes(s.spi.id);
|
||||||
}
|
}
|
||||||
await _getData(s.spi);
|
await _getData(s.spi);
|
||||||
@@ -75,7 +76,7 @@ class ServerProvider extends BusyProvider {
|
|||||||
|
|
||||||
void setDisconnected() {
|
void setDisconnected() {
|
||||||
for (var i = 0; i < _servers.length; i++) {
|
for (var i = 0; i < _servers.length; i++) {
|
||||||
_servers[i].cs = ServerState.disconnected;
|
_servers[i].state = ServerState.disconnected;
|
||||||
}
|
}
|
||||||
_limiter.clear();
|
_limiter.clear();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -135,14 +136,14 @@ class ServerProvider extends BusyProvider {
|
|||||||
Future<void> _getData(ServerPrivateInfo spi) async {
|
Future<void> _getData(ServerPrivateInfo spi) async {
|
||||||
final sid = spi.id;
|
final sid = spi.id;
|
||||||
final s = getServer(sid);
|
final s = getServer(sid);
|
||||||
final state = s.cs;
|
final state = s.state;
|
||||||
if (state.shouldConnect) {
|
if (state.shouldConnect) {
|
||||||
if (!_limiter.shouldTry(sid)) {
|
if (!_limiter.shouldTry(sid)) {
|
||||||
s.cs = ServerState.failed;
|
s.state = ServerState.failed;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.cs = ServerState.connecting;
|
s.state = ServerState.connecting;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -154,7 +155,7 @@ class ServerProvider extends BusyProvider {
|
|||||||
_logger.info('Connected to [$sid] in $spentTime ms.');
|
_logger.info('Connected to [$sid] in $spentTime ms.');
|
||||||
|
|
||||||
// after connected
|
// after connected
|
||||||
s.cs = ServerState.connected;
|
s.state = ServerState.connected;
|
||||||
final writeResult = await s.client!.run(installShellCmd).string;
|
final writeResult = await s.client!.run(installShellCmd).string;
|
||||||
|
|
||||||
// if write failed
|
// if write failed
|
||||||
@@ -163,8 +164,8 @@ class ServerProvider extends BusyProvider {
|
|||||||
}
|
}
|
||||||
_limiter.resetTryTimes(sid);
|
_limiter.resetTryTimes(sid);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
s.cs = ServerState.failed;
|
s.state = ServerState.failed;
|
||||||
s.status.failedInfo = '$e';
|
s.status.failedInfo = e.toString();
|
||||||
_logger.warning(e);
|
_logger.warning(e);
|
||||||
} finally {
|
} finally {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -176,7 +177,7 @@ class ServerProvider extends BusyProvider {
|
|||||||
final raw = await s.client!.run("sh $shellPath").string;
|
final raw = await s.client!.run("sh $shellPath").string;
|
||||||
final segments = raw.split(seperator).map((e) => e.trim()).toList();
|
final segments = raw.split(seperator).map((e) => e.trim()).toList();
|
||||||
if (raw.isEmpty || segments.length == 1) {
|
if (raw.isEmpty || segments.length == 1) {
|
||||||
s.cs = ServerState.failed;
|
s.state = ServerState.failed;
|
||||||
if (s.status.failedInfo == null || s.status.failedInfo!.isEmpty) {
|
if (s.status.failedInfo == null || s.status.failedInfo!.isEmpty) {
|
||||||
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
||||||
}
|
}
|
||||||
@@ -184,18 +185,14 @@ class ServerProvider extends BusyProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// remove first empty segment
|
// remove first empty segment
|
||||||
|
// for `export xxx` in shell script
|
||||||
segments.removeAt(0);
|
segments.removeAt(0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_getCPU(sid, segments[2], segments[7], segments[8]);
|
final req = ServerStatusUpdateReq(s.status, segments);
|
||||||
_getMem(sid, segments[6]);
|
s.status = await compute(_getStatus, req);
|
||||||
_getSysVer(sid, segments[1]);
|
|
||||||
_getUpTime(sid, segments[3]);
|
|
||||||
_getDisk(sid, segments[5]);
|
|
||||||
_getTcp(sid, segments[4]);
|
|
||||||
_getNetSpeed(sid, segments[0]);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
s.cs = ServerState.failed;
|
s.state = ServerState.failed;
|
||||||
s.status.failedInfo = e.toString();
|
s.status.failedInfo = e.toString();
|
||||||
_logger.warning(e);
|
_logger.warning(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -204,50 +201,6 @@ class ServerProvider extends BusyProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _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<void> _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<void> _getTcp(String id, String raw) async {
|
|
||||||
final status = await compute(parseTcp, raw);
|
|
||||||
if (status != null) {
|
|
||||||
getServer(id).status.tcp = status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _getDisk(String id, String raw) async {
|
|
||||||
getServer(id).status.disk = await compute(parseDisk, raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _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<String?> runSnippet(String id, Snippet snippet) async {
|
Future<String?> runSnippet(String id, Snippet snippet) async {
|
||||||
final client = getServer(id).client;
|
final client = getServer(id).client;
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
@@ -281,3 +234,55 @@ class _TryLimiter {
|
|||||||
_triedTimes.clear();
|
_triedTimes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ServerStatusUpdateReq {
|
||||||
|
final ServerStatus ss;
|
||||||
|
final List<String> segments;
|
||||||
|
|
||||||
|
const ServerStatusUpdateReq(this.ss, this.segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ServerStatus> _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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class SettingStore extends PersistentStore {
|
|||||||
|
|
||||||
/// Max retry count when connect to server
|
/// Max retry count when connect to server
|
||||||
StoreProperty<int> get maxRetryCount =>
|
StoreProperty<int> get maxRetryCount =>
|
||||||
property('maxRetryCount', defaultValue: 7);
|
property('maxRetryCount', defaultValue: 2);
|
||||||
|
|
||||||
/// Night mode: 0 -> auto, 1 -> light, 2 -> dark
|
/// Night mode: 0 -> auto, 1 -> light, 2 -> dark
|
||||||
StoreProperty<int> get themeMode => property('themeMode', defaultValue: 0);
|
StoreProperty<int> get themeMode => property('themeMode', defaultValue: 0);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
.go(context),
|
.go(context),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(13),
|
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')
|
onTap: () => AppRoute(ServerDetailPage(si.spi.id), 'server detail page')
|
||||||
.go(context),
|
.go(context),
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ class _SFTPPageState extends State<SFTPPage> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildFileView() {
|
Widget _buildFileView() {
|
||||||
if (_client == null || _si?.cs != ServerState.connected) {
|
if (_client == null || _si?.state != ServerState.connected) {
|
||||||
return centerCircleLoading;
|
return centerCircleLoading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user