Add reload back in (#808)

This commit is contained in:
Charlotte Weaver
2019-06-06 13:49:15 -07:00
committed by GitHub
parent 3edb87d125
commit 0f17b84dc1
+31 -28
View File
@@ -1,4 +1,5 @@
# flake8: noqa F403, F405 # flake8: noqa F403, F405
from functools import partialmethod
from multiprocessing import Pipe, Process from multiprocessing import Pipe, Process
from os.path import splitext, basename from os.path import splitext, basename
import sys import sys
@@ -26,11 +27,9 @@ class MainWindow(QMainWindow):
super(MainWindow, self).__init__(None) super(MainWindow, self).__init__(None)
self.cef_widget = None self.cef_widget = None
self.data_widget = None self.data_widget = None
self.parent_conn, self.child_conn = Pipe() self.parent_conn, self.child_conn = None, None
self.load_emitter = Emitter(self.parent_conn, WorkerSignals) self.load_emitter = None
self.load_emitter.signals.error.connect(self.restartOnError) self.emitter_thread = None
self.emitter_thread = threading.Thread(target=self.load_emitter.run, daemon=True)
self.emitter_thread.start()
self.worker = None self.worker = None
self.url = f"http://localhost:{GUI_PORT}/" self.url = f"http://localhost:{GUI_PORT}/"
self.setWindowTitle("cellxgene") self.setWindowTitle("cellxgene")
@@ -38,12 +37,10 @@ class MainWindow(QMainWindow):
# Strong focus - accepts focus by tab & click # Strong focus - accepts focus by tab & click
self.setFocusPolicy(Qt.StrongFocus) self.setFocusPolicy(Qt.StrongFocus)
self.setupLayout() self.setupLayout()
# self.setupMenu() self.setupMenu()
def restartOnError(self): def restartOnError(self):
if self.worker: self.window().shutdownServer()
self.worker.terminate()
self.parent_conn.close()
# close emitter on error/finished # close emitter on error/finished
self.parent_conn, self.child_conn = Pipe() self.parent_conn, self.child_conn = Pipe()
self.load_emitter = Emitter(self.parent_conn, WorkerSignals) self.load_emitter = Emitter(self.parent_conn, WorkerSignals)
@@ -85,6 +82,21 @@ class MainWindow(QMainWindow):
self.cef_widget.hidden_window, parent=self) self.cef_widget.hidden_window, parent=self)
self.stacked_layout.addWidget(self.container, 1, 0) self.stacked_layout.addWidget(self.container, 1, 0)
def setupServer(self):
self.shutdownServer()
# close emitter on error/finished
self.parent_conn, self.child_conn = Pipe()
self.load_emitter = Emitter(self.parent_conn, WorkerSignals)
self.emitter_thread = threading.Thread(target=self.load_emitter.run, daemon=True)
self.emitter_thread.start()
# send to load with error message?
def shutdownServer(self):
if self.worker:
self.worker.terminate()
if self.parent_conn:
self.parent_conn.close()
def setupMenu(self): def setupMenu(self):
# TODO add communication to subprocess on reload # TODO add communication to subprocess on reload
main_menu = self.menuBar() main_menu = self.menuBar()
@@ -171,10 +183,11 @@ class LoadWidget(QFrame):
self.embedding_selection = [MODES[idx]] self.embedding_selection = [MODES[idx]]
def createScanpyEngine(self, file_name): def createScanpyEngine(self, file_name):
self.window().setupServer()
worker = Worker(self.window().parent_conn, self.window().child_conn, file_name, self.title, host="127.0.0.1", port=GUI_PORT, worker = Worker(self.window().parent_conn, self.window().child_conn, file_name, self.title, host="127.0.0.1", port=GUI_PORT,
layout=self.embedding_selection) layout=self.embedding_selection)
self.window().load_emitter.signals.ready.connect(self.onDataReady) self.window().load_emitter.signals.ready.connect(self.onDataReady)
self.window().load_emitter.signals.engine_error.connect(self.onEngineError) self.window().load_emitter.signals.engine_error.connect(self.onServerError)
self.window().load_emitter.signals.server_error.connect(self.onServerError) self.window().load_emitter.signals.server_error.connect(self.onServerError)
# Error is generic error from emitter # Error is generic error from emitter
self.window().load_emitter.signals.error.connect(self.onServerError) self.window().load_emitter.signals.error.connect(self.onServerError)
@@ -196,7 +209,7 @@ class LoadWidget(QFrame):
def onDataReady(self): def onDataReady(self):
self.site_ready_worker = SiteReadyWorker(self.window().url) self.site_ready_worker = SiteReadyWorker(self.window().url)
self.site_ready_worker.signals.ready.connect(self.onServerReady) self.site_ready_worker.signals.ready.connect(self.onServerReady)
self.site_ready_worker.signals.error.connect(self.onDataError) self.site_ready_worker.signals.error.connect(self.onError)
srw_thread = threading.Thread(target=self.site_ready_worker.run, daemon=True) srw_thread = threading.Thread(target=self.site_ready_worker.run, daemon=True)
srw_thread.start() srw_thread.start()
@@ -206,26 +219,17 @@ class LoadWidget(QFrame):
self.window().cef_widget.browser.Navigate(self.window().url) self.window().cef_widget.browser.Navigate(self.window().url)
self.window().stacked_layout.setCurrentIndex(1) self.window().stacked_layout.setCurrentIndex(1)
def onServerError(self, err): def onError(self, err, server_error=False):
# Restart worker # Restart worker
self.serverError = True if server_error:
# Report error and switch to load screen self.serverError = True
self.window().restartOnError() # Report error and switch to load screen
self.window().shutdownServer()
self.window().stacked_layout.setCurrentIndex(0) self.window().stacked_layout.setCurrentIndex(0)
self.error_label.setText(f"Error: {err}") self.error_label.setText(f"Error: {err}")
self.error_label.resize(self.MAX_CONTENT_WIDTH, self.error_label.height()) self.error_label.resize(self.MAX_CONTENT_WIDTH, self.error_label.height())
def onEngineError(self, err): onServerError = partialmethod(onError, server_error=True)
self.window().restartOnError()
self.window().stacked_layout.setCurrentIndex(0)
self.error_label.setText(f"Error: {err}")
self.error_label.resize(self.MAX_CONTENT_WIDTH, self.error_label.height())
def onDataError(self, err):
self.window().restartOnError()
self.window().stacked_layout.setCurrentIndex(0)
self.error_label.setText(f"Error: {err}")
self.error_label.resize(self.MAX_CONTENT_WIDTH, self.error_label.height())
def main(): def main():
@@ -252,8 +256,7 @@ def main():
if not cef.GetAppSetting("external_message_pump"): if not cef.GetAppSetting("external_message_pump"):
app.stopTimer() app.stopTimer()
if main_window.worker: main_window.shutdownServer()
main_window.worker.terminate()
del main_window # Just to be safe, similarly to "del app" del main_window # Just to be safe, similarly to "del app"
del app # Must destroy app object before calling Shutdown del app # Must destroy app object before calling Shutdown
cef.Shutdown() cef.Shutdown()