mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-13 09:48:10 +03:00
Keep disconnect and quit responsive
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -96,6 +96,7 @@ class ConnectionController(QtCore.QObject):
|
||||
progressFinished = QtCore.Signal(bool)
|
||||
notificationRequested = QtCore.Signal(str)
|
||||
errorOccurred = QtCore.Signal(object)
|
||||
shutdownFinished = QtCore.Signal(bool)
|
||||
|
||||
def __init__(self, parent=None, *, coreManager=None, updatesManager=None):
|
||||
"""Initialize reusable runtime services and a disconnected state."""
|
||||
@@ -114,6 +115,12 @@ class ConnectionController(QtCore.QObject):
|
||||
self._startAdmissionPending = False
|
||||
self._shuttingDown = False
|
||||
self._runtimeCleanupFailed = False
|
||||
self._stopOperation = None
|
||||
self._disconnectionGeneration = 0
|
||||
self._disconnectionNotification = ''
|
||||
self._reconnectAfterStop = False
|
||||
self._shutdownConnectPreference = None
|
||||
self._shutdownComplete = False
|
||||
|
||||
self._actionTimer = QtCore.QTimer(self)
|
||||
self._actionTimer.timeout.connect(self._callActionFromQueue)
|
||||
@@ -175,7 +182,11 @@ class ConnectionController(QtCore.QObject):
|
||||
|
||||
self.stateChanged.emit(state)
|
||||
|
||||
if generation != self._connectionGeneration or self._state is not state:
|
||||
if (
|
||||
not isValid(self)
|
||||
or generation != self._connectionGeneration
|
||||
or self._state is not state
|
||||
):
|
||||
return
|
||||
|
||||
if self.interactionEnabled != interactionWasEnabled:
|
||||
@@ -213,7 +224,11 @@ class ConnectionController(QtCore.QObject):
|
||||
self._pendingHttpProxy = ''
|
||||
|
||||
self.progressFinished.emit(True)
|
||||
if not isValid(self):
|
||||
return
|
||||
self._setActiveProfile(None)
|
||||
if not isValid(self):
|
||||
return
|
||||
|
||||
AppSettings.turnOFF('Connect')
|
||||
|
||||
@@ -571,9 +586,16 @@ class ConnectionController(QtCore.QObject):
|
||||
|
||||
def startDisconnection(self, notification: str = '') -> bool:
|
||||
"""Stop the active runtime and optionally request a notification."""
|
||||
if self.isDisconnecting() or (
|
||||
if self.isDisconnecting():
|
||||
self._reconnectAfterStop = False
|
||||
return False
|
||||
if (
|
||||
self.state is ConnectionState.Disconnected
|
||||
and not self._startAdmissionPending
|
||||
and not (
|
||||
self._shuttingDown
|
||||
and callable(getattr(self._coreManager, 'stopAsync', None))
|
||||
)
|
||||
):
|
||||
return False
|
||||
|
||||
@@ -588,6 +610,8 @@ class ConnectionController(QtCore.QObject):
|
||||
self._startOperation = None
|
||||
|
||||
self._setState(ConnectionState.Disconnecting)
|
||||
if not isValid(self) or generation != self._connectionGeneration:
|
||||
return True
|
||||
self._actionTimer.stop()
|
||||
|
||||
if operation is not None and isValid(operation):
|
||||
@@ -609,6 +633,33 @@ class ConnectionController(QtCore.QObject):
|
||||
logger.error(f'failed to turn off system proxy: {ex}')
|
||||
|
||||
self._runtimeCleanupFailed = False
|
||||
self._disconnectionGeneration = generation
|
||||
self._disconnectionNotification = notification
|
||||
|
||||
asyncStop = getattr(self._coreManager, 'stopAsync', None)
|
||||
if callable(asyncStop):
|
||||
try:
|
||||
self._stopOperation = stopOperation = asyncStop()
|
||||
connectWeakly(
|
||||
stopOperation.finished,
|
||||
self,
|
||||
'_connectionStopFinished',
|
||||
sender=stopOperation,
|
||||
)
|
||||
connectWeakly(
|
||||
stopOperation.destroyed,
|
||||
self,
|
||||
'_connectionStopDestroyed',
|
||||
sender=stopOperation,
|
||||
)
|
||||
stopOperation.start()
|
||||
return True
|
||||
except Exception as ex:
|
||||
# Any non-exit exceptions
|
||||
self._runtimeCleanupFailed = True
|
||||
logger.error(f'failed to stop connection runtime: {ex}')
|
||||
self._finishDisconnection(generation, notification)
|
||||
return True
|
||||
|
||||
try:
|
||||
self._coreManager.stopAll()
|
||||
@@ -621,10 +672,36 @@ class ConnectionController(QtCore.QObject):
|
||||
|
||||
logger.error(f'failed to stop connection runtime: {ex}')
|
||||
|
||||
self._finishDisconnection(generation, notification)
|
||||
return True
|
||||
|
||||
def _connectionStopFinished(self, operation, error):
|
||||
if operation is not self._stopOperation:
|
||||
return
|
||||
self._stopOperation = None
|
||||
if error:
|
||||
self._runtimeCleanupFailed = True
|
||||
logger.error(f'failed to stop connection runtime: {error}')
|
||||
self._finishDisconnection(
|
||||
self._disconnectionGeneration, self._disconnectionNotification
|
||||
)
|
||||
|
||||
def _connectionStopDestroyed(self, *_args):
|
||||
if self._stopOperation is not None and not isValid(self._stopOperation):
|
||||
self._stopOperation = None
|
||||
self._runtimeCleanupFailed = True
|
||||
self._finishDisconnection(
|
||||
self._disconnectionGeneration, self._disconnectionNotification
|
||||
)
|
||||
|
||||
def _finishDisconnection(self, generation, notification):
|
||||
reconnect, self._reconnectAfterStop = self._reconnectAfterStop, False
|
||||
self._emitRuntimesChanged()
|
||||
if not isValid(self):
|
||||
return
|
||||
self._reset()
|
||||
|
||||
if generation != self._connectionGeneration:
|
||||
if not isValid(self) or generation != self._connectionGeneration:
|
||||
return True
|
||||
|
||||
while not self._actionQueue.empty():
|
||||
@@ -636,9 +713,29 @@ class ConnectionController(QtCore.QObject):
|
||||
pass
|
||||
|
||||
Mixins.ConnectionAware.callDisconnectedCallback()
|
||||
if not isValid(self) or generation != self._connectionGeneration:
|
||||
return
|
||||
|
||||
if notification:
|
||||
self.notificationRequested.emit(notification)
|
||||
if not isValid(self):
|
||||
return
|
||||
|
||||
if self._shuttingDown:
|
||||
if self._shutdownConnectPreference:
|
||||
AppSettings.turnON_('Connect')
|
||||
success = not self._runtimeCleanupFailed
|
||||
self._shutdownComplete = success
|
||||
if not success:
|
||||
self._shuttingDown = False
|
||||
self._shutdownConnectPreference = None
|
||||
self.shutdownFinished.emit(success)
|
||||
elif (
|
||||
reconnect
|
||||
and not self._runtimeCleanupFailed
|
||||
and generation == self._connectionGeneration
|
||||
):
|
||||
self.startConnection()
|
||||
|
||||
return True
|
||||
|
||||
@@ -648,7 +745,8 @@ class ConnectionController(QtCore.QObject):
|
||||
return False
|
||||
|
||||
if self.isConnected() or self.isConnecting():
|
||||
self.startDisconnection(notification)
|
||||
self._reconnectAfterStop = True
|
||||
return self.startDisconnection(notification)
|
||||
|
||||
return self.startConnection()
|
||||
|
||||
@@ -661,7 +759,13 @@ class ConnectionController(QtCore.QObject):
|
||||
|
||||
def shutdown(self):
|
||||
"""Stop runtime resources without changing the next-start preference."""
|
||||
if self._shutdownComplete:
|
||||
self.shutdownFinished.emit(True)
|
||||
return True
|
||||
reconnectOnStartup = AppSettings.isStateON_('Connect')
|
||||
if self._shutdownConnectPreference is None:
|
||||
self._shutdownConnectPreference = reconnectOnStartup
|
||||
reconnectOnStartup = self._shutdownConnectPreference
|
||||
|
||||
self._shuttingDown = True
|
||||
|
||||
@@ -669,16 +773,29 @@ class ConnectionController(QtCore.QObject):
|
||||
if (
|
||||
self.state is not ConnectionState.Disconnected
|
||||
or self._startAdmissionPending
|
||||
or callable(getattr(self._coreManager, 'stopAsync', None))
|
||||
):
|
||||
self.startDisconnection()
|
||||
|
||||
if self.isDisconnecting() or not self._shuttingDown:
|
||||
return False
|
||||
|
||||
if not self._runtimeCleanupFailed:
|
||||
return
|
||||
return True
|
||||
|
||||
# Disconnect keeps the UI usable on failure. Final shutdown must
|
||||
# surface retained resources before its owner is destroyed.
|
||||
self._coreManager.stopAll()
|
||||
self._runtimeCleanupFailed = False
|
||||
self._shutdownComplete = True
|
||||
self.shutdownFinished.emit(True)
|
||||
return True
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
self._shuttingDown = False
|
||||
self._shutdownConnectPreference = None
|
||||
self.shutdownFinished.emit(False)
|
||||
raise
|
||||
finally:
|
||||
if reconnectOnStartup:
|
||||
AppSettings.turnON_('Connect')
|
||||
|
||||
Reference in New Issue
Block a user