Skip to content

Commit

Permalink
Improved DS interop performance
Browse files Browse the repository at this point in the history
The DB mode server socket doesn't run when auto resize is off
  • Loading branch information
Gold872 committed Jul 22, 2024
1 parent 189d21f commit 8392734
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 32 deletions.
15 changes: 10 additions & 5 deletions lib/pages/dashboard_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
},
);

if (widget.preferences.getBool(PrefKeys.autoResizeToDS) ??
Defaults.autoResizeToDS) {
widget.ntConnection.startDBModeServer();
}

widget.ntConnection.addConnectedListener(() {
setState(() {
for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) {
Expand Down Expand Up @@ -1101,15 +1106,16 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
});
},
onResizeToDSChanged: (value) async {
await preferences.setBool(PrefKeys.autoResizeToDS, value);

setState(() {
if (value && widget.ntConnection.dsClient.driverStationDocked) {
_onDriverStationDocked();
if (value) {
widget.ntConnection.startDBModeServer();
} else {
widget.ntConnection.stopDBModeServer();
_onDriverStationUndocked();
}
});

await preferences.setBool(PrefKeys.autoResizeToDS, value);
},
onRememberWindowPositionChanged: (value) async {
await preferences.setBool(PrefKeys.rememberWindowPosition, value);
Expand Down Expand Up @@ -1182,7 +1188,6 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
pixelRatio;

await windowManager.setSize(newScreenSize);

await windowManager.setAlignment(Alignment.topCenter);

Settings.isWindowMaximizable = false;
Expand Down
89 changes: 62 additions & 27 deletions lib/services/ds_interop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:elastic_dashboard/services/log.dart';
class DSInteropClient {
final String serverBaseAddress = '127.0.0.1';
bool _serverConnectionActive = false;
bool _dbModeConnectionActive = false;
bool _dbModeServerRunning = false;

Function()? onConnect;
Function()? onDisconnect;
Expand All @@ -20,6 +20,8 @@ class DSInteropClient {
Socket? _socket;
ServerSocket? _dbModeServer;

final List<Socket> _connectedSockets = [];

List<int> _tcpBuffer = [];

String? _lastAnnouncedIP;
Expand All @@ -28,21 +30,34 @@ class DSInteropClient {
String? get lastAnnouncedIP => _lastAnnouncedIP;
bool get driverStationDocked => _driverStationDocked;

bool _attemptServerStart = true;

DateTime serverStopTime = DateTime.now();

DSInteropClient({
this.onNewIPAnnounced,
this.onDriverStationDockChanged,
this.onConnect,
this.onDisconnect,
}) {
_connect();
_tcpSocketConnect();
}

void _connect() {
if (_serverConnectionActive) {
return;
void startDBModeServer() {
// For some reason if the server is quickly stopped then started there's a 5 second delay
// The workaround is to use the cached value of the docked state
if (DateTime.now().microsecondsSinceEpoch -
serverStopTime.microsecondsSinceEpoch <=
5 * 1e6) {
onDriverStationDockChanged?.call(_driverStationDocked);
}
_tcpSocketConnect();
_dbModeServerConnect();
_attemptServerStart = true;
_startDBModeServer();
}

void stopDBModeServer() {
serverStopTime = DateTime.now();
_dbModeServerClose(false);
}

void _tcpSocketConnect() async {
Expand Down Expand Up @@ -74,30 +89,36 @@ class DSInteropClient {
);
}

void _dbModeServerConnect() async {
if (_dbModeConnectionActive) {
Future<void> _startDBModeServer() async {
if (_dbModeServerRunning || !_attemptServerStart) {
return;
}
try {
_dbModeServer = await ServerSocket.bind(serverBaseAddress, 1741);
} catch (e) {
logger.info(
'Failed to start TCP server on port 1741, attempting to reconnect in 5 seconds');
Future.delayed(const Duration(seconds: 5), _dbModeServerConnect);
if (_attemptServerStart) {
logger.info(
'Failed to start TCP server on port 1741, attempting to restart in 5 seconds');
Future.delayed(const Duration(seconds: 5), _startDBModeServer);
} else {
logger.info('Failed to start TCP server on port 1741');
}
return;
}

_attemptServerStart = false;
_dbModeServerRunning = true;

_dbModeServer!.listen(
(socket) {
logger.info('Received connection from Driver Station on TCP port 1741');
_connectedSockets.add(socket);
socket.listen(
(data) {
if (!_dbModeConnectionActive) {
_dbModeConnectionActive = true;
}
_dbModeServerOnMessage(data);
},
onDone: () {
_connectedSockets.remove(socket);
logger.info('Lost connection from Driver Station on TCP port 1741');
},
);
Expand Down Expand Up @@ -172,39 +193,53 @@ class DSInteropClient {
}
}

void _socketClose() {
void _socketClose() async {
if (!_serverConnectionActive) {
return;
}

_socket?.close();
await _socket?.close();
_socket = null;

_serverConnectionActive = false;

_driverStationDocked = false;
onDriverStationDockChanged?.call(false);
onDisconnect?.call();

logger.info(
'Driver Station connection on TCP port 1742 closed, attempting to reconnect in 5 seconds.');

Future.delayed(const Duration(seconds: 5), _connect);
Future.delayed(const Duration(seconds: 5), _tcpSocketConnect);
}

void _dbModeServerClose() {
if (!_dbModeConnectionActive) {
void _dbModeServerClose([bool reconnect = true]) async {
if (!_dbModeServerRunning) {
return;
}

_dbModeServer?.close();
_dbModeServerRunning = false;

// Cloning the list because closing each socket changes the size of the list
for (Socket socket in _connectedSockets.toList()) {
await socket.close();
socket.destroy();
}

await _dbModeServer?.close();
_dbModeServer = null;

_dbModeConnectionActive = false;
onDriverStationDockChanged?.call(false);

logger.info(
'Driver Station TCP Server on Port 1741 closed, attempting to reconnect in 5 seconds.');
_tcpBuffer.clear();

_attemptServerStart = reconnect;

Future.delayed(const Duration(seconds: 5), _dbModeServerConnect);
if (reconnect) {
logger.info(
'Driver Station TCP Server on Port 1741 closed, attempting to reconnect in 5 seconds.');

Future.delayed(const Duration(seconds: 5), _startDBModeServer);
} else {
logger.info('Driver Station TCP Server on Port 1741 closed');
}
}
}
8 changes: 8 additions & 0 deletions lib/services/nt_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ class NTConnection {
);
}

void startDBModeServer() {
_dsClient.startDBModeServer();
}

void stopDBModeServer() {
_dsClient.stopDBModeServer();
}

void addConnectedListener(VoidCallback callback) {
onConnectedListeners.add(callback);
}
Expand Down

0 comments on commit 8392734

Please sign in to comment.