From eade3a351c946f3efd5642163e029b570a19c68a Mon Sep 17 00:00:00 2001 From: Mariusz Jurowicz Date: Tue, 26 Jun 2018 15:52:43 +0200 Subject: [PATCH] #7568 fix SparkUI connection status widget in multiple notebooks (#7581) * #7568 handle spark status toolbar on multiple notebooks * #7522 handling appId/host get paramters in spark metrics api * #7568 fix SparkUI connection status widget in multiple notebooks --- beakerx/beakerx/handlers.py | 9 ++- js/notebook/src/SparkUI.ts | 58 +++++++++++-------- .../sparkUI/toolbarSparkConnectionStatus.ts | 4 +- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/beakerx/beakerx/handlers.py b/beakerx/beakerx/handlers.py index 19e43c80e9..a2cc1548c2 100644 --- a/beakerx/beakerx/handlers.py +++ b/beakerx/beakerx/handlers.py @@ -29,12 +29,15 @@ def data_received(self, chunk): @web.authenticated @tornado.web.asynchronous - def get(self, id): + def get(self): def handle_response(response): self.finish(response.body) - url = "http://localhost:4040/api/v1/applications/" + id + "/allexecutors" + app_id = self.get_argument('sparkAppId', None) + ui_web_url = self.get_argument('sparkUiWebUrl', None) + + url = ui_web_url + "/api/v1/applications/" + app_id + "/allexecutors" req = tornado.httpclient.HTTPRequest( url=url, method=self.request.method, @@ -104,7 +107,7 @@ def load_jupyter_server_extension(nbapp): web_app = nbapp.web_app host_pattern = '.*$' settings_route_pattern = url_path_join(web_app.settings['base_url'], '/beakerx', '/settings') - spark_metrics_executors_route_pattern = url_path_join(web_app.settings['base_url'], '/beakerx', '/sparkmetrics/executors/(.*)') + spark_metrics_executors_route_pattern = url_path_join(web_app.settings['base_url'], '/beakerx', '/sparkmetrics/executors') version_route_pattern = url_path_join(web_app.settings['base_url'], '/beakerx', '/version') javadoc_route_pattern = url_path_join(web_app.settings['base_url'], '/static', '/javadoc/(.*)') javadoc_lab_route_pattern = url_path_join(web_app.settings['base_url'], '/javadoc/(.*)') diff --git a/js/notebook/src/SparkUI.ts b/js/notebook/src/SparkUI.ts index e95265a8d1..27cf231784 100644 --- a/js/notebook/src/SparkUI.ts +++ b/js/notebook/src/SparkUI.ts @@ -42,11 +42,11 @@ export class SparkUIView extends widgets.VBoxView { sparkStats: Widget; connectionStatusElement: HTMLElement; + private api: BeakerXApi; private sparkAppId: string; private sparkUiWebUrl: string; private sparkMasterUrl: string; private apiCallIntervalId: Timer; - private toolbarStatusContainer: HTMLElement|null; private connectionLabelActive: HTMLElement; private connectionLabelMemory: HTMLElement; private connectionLabelDead: HTMLElement; @@ -62,6 +62,7 @@ export class SparkUIView extends widgets.VBoxView { this.openExecutors = this.openExecutors.bind(this); this.updateChildren = this.updateChildren.bind(this); this.toggleExecutorConfigInputs = this.toggleExecutorConfigInputs.bind(this); + this.getMetrict = this.getMetrict.bind(this); this.toolbarSparkConnectionStatus = new ToolbarSparkConnectionStatus(this); } @@ -77,7 +78,6 @@ export class SparkUIView extends widgets.VBoxView { public update(): void { super.update(); - this.connectToApi(); this.addSparkMetricsWidget(); this.handleLocalMasterUrl(); this.updateChildren(); @@ -214,6 +214,7 @@ export class SparkUIView extends widgets.VBoxView { this.handleLocalMasterUrl(); this.toolbarSparkConnectionStatus.append(); this.addSparkUrls(); + this.connectToApi(); this.handleFormState(); this.toggleExecutorConfigInputs(); this.setupTooltips(); @@ -267,13 +268,10 @@ export class SparkUIView extends widgets.VBoxView { this.sparkStats.node.style.marginRight = `${294 - (this.sparkStats.node.offsetWidth + this.connectionStatusElement.offsetWidth)}px`; } - private connectToApi() { + private setApi() { let baseUrl; - let api; - - this.sparkAppId = this.model.get('sparkAppId'); - if (!this.sparkAppId) { + if (this.api) { return; } @@ -285,31 +283,41 @@ export class SparkUIView extends widgets.VBoxView { baseUrl = `${window.location.origin}/`; } - api = new BeakerXApi(baseUrl); - this.setApiCallInterval(api); + this.api = new BeakerXApi(baseUrl); } - private setApiCallInterval(api: BeakerXApi): void { - const sparkUrl = `${api.getApiUrl('sparkmetrics/executors')}/${this.sparkAppId}`; - const getMetrict = async () => { - try { - const response = await fetch(sparkUrl, { method: 'GET', credentials: 'include' }); + private connectToApi() { + this.setApi(); + this.setApiCallInterval(); + } - if (!response.ok) { - this.toolbarSparkConnectionStatus.destroy(); - return this.clearApiCallInterval(); - } + private setApiCallInterval(): void { + this.clearApiCallInterval(); + this.sparkAppId = this.model.get('sparkAppId'); - const data = await response.json(); - this.updateMetrics(data); - } catch(error) { + if (!this.sparkUiWebUrl || !this.sparkAppId) { + return; + } + + this.apiCallIntervalId = setInterval(this.getMetrict, 1000); + } + + private async getMetrict() { + try { + let sparkUrl = `${this.api.getApiUrl('sparkmetrics/executors')}?sparkAppId=${this.sparkAppId}&sparkUiWebUrl=${this.sparkUiWebUrl}`; + const response = await fetch(sparkUrl, { method: 'GET', credentials: 'include' }); + + if (!response.ok) { this.toolbarSparkConnectionStatus.destroy(); - this.clearApiCallInterval(); + return this.clearApiCallInterval(); } - }; - this.clearApiCallInterval(); - this.apiCallIntervalId = setInterval(getMetrict, 1000); + const data = await response.json(); + this.updateMetrics(data); + } catch(error) { + this.toolbarSparkConnectionStatus.destroy(); + this.clearApiCallInterval(); + } } private clearApiCallInterval() { diff --git a/js/notebook/src/sparkUI/toolbarSparkConnectionStatus.ts b/js/notebook/src/sparkUI/toolbarSparkConnectionStatus.ts index de5d9d6bd0..498d0d5d3d 100644 --- a/js/notebook/src/sparkUI/toolbarSparkConnectionStatus.ts +++ b/js/notebook/src/sparkUI/toolbarSparkConnectionStatus.ts @@ -42,7 +42,9 @@ export class ToolbarSparkConnectionStatus { } clear() { - this.toolbarSparkStats.node.innerHTML = ''; + if (this.toolbarSparkStats) { + this.toolbarSparkStats.node.innerHTML = ''; + } } propagateToolbarWidget() {