mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 15:24:35 +01:00
new: manual refresh failed servers
This commit is contained in:
@@ -3,27 +3,29 @@ import 'package:toolbox/data/res/store.dart';
|
|||||||
class TryLimiter {
|
class TryLimiter {
|
||||||
final Map<String, int> _triedTimes = {};
|
final Map<String, int> _triedTimes = {};
|
||||||
|
|
||||||
bool canTry(String id) {
|
static final _default = TryLimiter();
|
||||||
|
|
||||||
|
static bool canTry(String id) {
|
||||||
final maxCount = Stores.setting.maxRetryCount.fetch();
|
final maxCount = Stores.setting.maxRetryCount.fetch();
|
||||||
if (maxCount <= 0) {
|
if (maxCount <= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final times = _triedTimes[id] ?? 0;
|
final times = _default._triedTimes[id] ?? 0;
|
||||||
if (times >= maxCount) {
|
if (times >= maxCount) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void inc(String sid) {
|
static void inc(String sid) {
|
||||||
_triedTimes[sid] = (_triedTimes[sid] ?? 0) + 1;
|
_default._triedTimes[sid] = (_default._triedTimes[sid] ?? 0) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(String id) {
|
static void reset(String id) {
|
||||||
_triedTimes[id] = 0;
|
_default._triedTimes[id] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
static void clear() {
|
||||||
_triedTimes.clear();
|
_default._triedTimes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
final List<String> _tags = [];
|
final List<String> _tags = [];
|
||||||
List<String> get tags => _tags;
|
List<String> get tags => _tags;
|
||||||
|
|
||||||
final _limiter = TryLimiter();
|
|
||||||
|
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
@@ -124,7 +122,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
Future<void> _connectFn(Server s, bool onlyFailed) async {
|
Future<void> _connectFn(Server s, bool onlyFailed) async {
|
||||||
if (onlyFailed) {
|
if (onlyFailed) {
|
||||||
if (s.state != ServerState.failed) return;
|
if (s.state != ServerState.failed) return;
|
||||||
_limiter.reset(s.spi.id);
|
TryLimiter.reset(s.spi.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If [spi.autoConnect] is false and server is disconnected, then skip.
|
/// If [spi.autoConnect] is false and server is disconnected, then skip.
|
||||||
@@ -161,7 +159,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
for (final s in _servers.values) {
|
for (final s in _servers.values) {
|
||||||
s.state = ServerState.disconnected;
|
s.state = ServerState.disconnected;
|
||||||
}
|
}
|
||||||
_limiter.clear();
|
//TryLimiter.clear();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +225,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
// Only reconnect if neccessary
|
// Only reconnect if neccessary
|
||||||
if (newSpi.shouldReconnect(old)) {
|
if (newSpi.shouldReconnect(old)) {
|
||||||
// Use [newSpi.id] instead of [old.id] because [old.id] may be changed
|
// Use [newSpi.id] instead of [old.id] because [old.id] may be changed
|
||||||
_limiter.reset(newSpi.id);
|
TryLimiter.reset(newSpi.id);
|
||||||
refreshData(spi: newSpi);
|
refreshData(spi: newSpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +254,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
if (s == null) return;
|
if (s == null) return;
|
||||||
|
|
||||||
if (!_limiter.canTry(sid)) {
|
if (!TryLimiter.canTry(sid)) {
|
||||||
if (s.state != ServerState.failed) {
|
if (s.state != ServerState.failed) {
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
}
|
}
|
||||||
@@ -289,7 +287,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo = e.toString();
|
s.status.failedInfo = e.toString();
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
|
|
||||||
@@ -332,7 +330,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo = e.toString();
|
s.status.failedInfo = e.toString();
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
Loggers.app.warning('Write script to ${spi.name} by sftp', e);
|
Loggers.app.warning('Write script to ${spi.name} by sftp', e);
|
||||||
@@ -357,13 +355,13 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
raw = await s.client?.run(ShellFunc.status.exec).string;
|
raw = await s.client?.run(ShellFunc.status.exec).string;
|
||||||
segments = raw?.split(seperator).map((e) => e.trim()).toList();
|
segments = raw?.split(seperator).map((e) => e.trim()).toList();
|
||||||
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
|
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo = e.toString();
|
s.status.failedInfo = e.toString();
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
Loggers.app.warning('Get status from ${spi.name} failed', e);
|
Loggers.app.warning('Get status from ${spi.name} failed', e);
|
||||||
@@ -372,7 +370,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
final systemType = SystemType.parse(segments[0]);
|
final systemType = SystemType.parse(segments[0]);
|
||||||
if (!systemType.isSegmentsLenMatch(segments.length)) {
|
if (!systemType.isSegmentsLenMatch(segments.length)) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo =
|
s.status.failedInfo =
|
||||||
'Segments not match: expect ${systemType.segmentsLen}, got ${segments.length}';
|
'Segments not match: expect ${systemType.segmentsLen}, got ${segments.length}';
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
@@ -388,7 +386,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
s.status = await compute(getStatus, req);
|
s.status = await compute(getStatus, req);
|
||||||
} catch (e, trace) {
|
} catch (e, trace) {
|
||||||
_limiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.failedInfo = 'Parse failed: $e\n\n$raw';
|
s.status.failedInfo = 'Parse failed: $e\n\n$raw';
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
Loggers.parse.warning('Server status', e, trace);
|
Loggers.parse.warning('Server status', e, trace);
|
||||||
@@ -398,7 +396,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
/// Call this every time for setting [Server.isBusy] to false
|
/// Call this every time for setting [Server.isBusy] to false
|
||||||
_setServerState(s, ServerState.finished);
|
_setServerState(s, ServerState.finished);
|
||||||
// reset try times only after prepared successfully
|
// reset try times only after prepared successfully
|
||||||
_limiter.reset(sid);
|
TryLimiter.reset(sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SnippetResult?> runSnippets(String id, Snippet snippet) async {
|
Future<SnippetResult?> runSnippets(String id, Snippet snippet) async {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:toolbox/core/extension/ssh_client.dart';
|
|||||||
import 'package:toolbox/core/utils/platform/base.dart';
|
import 'package:toolbox/core/utils/platform/base.dart';
|
||||||
import 'package:toolbox/core/utils/share.dart';
|
import 'package:toolbox/core/utils/share.dart';
|
||||||
import 'package:toolbox/data/model/app/shell_func.dart';
|
import 'package:toolbox/data/model/app/shell_func.dart';
|
||||||
|
import 'package:toolbox/data/model/server/try_limiter.dart';
|
||||||
import 'package:toolbox/data/res/provider.dart';
|
import 'package:toolbox/data/res/provider.dart';
|
||||||
import 'package:toolbox/data/res/store.dart';
|
import 'package:toolbox/data/res/store.dart';
|
||||||
|
|
||||||
@@ -335,7 +336,22 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
ServerPrivateInfo spi,
|
ServerPrivateInfo spi,
|
||||||
) {
|
) {
|
||||||
Widget? rightCorner;
|
Widget? rightCorner;
|
||||||
if (!(spi.autoConnect ?? true) && cs == ServerState.disconnected) {
|
if (cs == ServerState.failed) {
|
||||||
|
rightCorner = InkWell(
|
||||||
|
onTap: () {
|
||||||
|
TryLimiter.reset(spi.id);
|
||||||
|
Pros.server.refreshData(spi: spi);
|
||||||
|
},
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 7),
|
||||||
|
child: Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
size: 21,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (!(spi.autoConnect ?? true) && cs == ServerState.disconnected) {
|
||||||
rightCorner = InkWell(
|
rightCorner = InkWell(
|
||||||
onTap: () => Pros.server.refreshData(spi: spi),
|
onTap: () => Pros.server.refreshData(spi: spi),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
|
|||||||
Reference in New Issue
Block a user