Skip to content

Commit

Permalink
#7521 improve SparkUI status widget (#7532)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariusz Jurowicz authored and scottdraves committed Jun 15, 2018
1 parent ae16686 commit 6d2ab65
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 13 deletions.
69 changes: 68 additions & 1 deletion js/notebook/src/SparkConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import widgets from './widgets';
import Timer = NodeJS.Timer;

export class SparkConfigurationModel extends widgets.VBoxModel {
defaults() {
Expand All @@ -30,7 +31,73 @@ export class SparkConfigurationModel extends widgets.VBoxModel {
}
}

export class SparkConfigurationView extends widgets.VBoxView {}
export class SparkConfigurationView extends widgets.VBoxView {
update() {
super.update();
this.updateChildren();
}

render() {
super.render();
this.updateChildren();
}

private handleFormState() {
const configButtons = this.el.querySelectorAll('.bx-spark-configuration .bx-button');
const configurationInputs = this.el.querySelectorAll('.bx-spark-configuration input');

if (this.el.closest('.bx-disabled')) {
this.setFormReadonly(configButtons, configurationInputs);
} else {
this.setFormEditable(configButtons, configurationInputs);
}
}

private setFormReadonly(configButtons, configurationInputs) {
configurationInputs && configurationInputs.forEach(input => input.setAttribute('readonly', 'readonly'));
configButtons && configButtons.forEach(button => button.setAttribute('disabled', 'disabled'));
}

private setFormEditable(configButtons, configurationInputs) {
configurationInputs && configurationInputs.forEach(input => input.removeAttribute('readonly'));
configButtons && configButtons.forEach(button => button.removeAttribute('readonly'));
}

private updateChildren() {
const noop = () => {};
let updateTimer: Timer;

this.resolveChildren(this).then((views) => {
views.forEach((view) => {
this.resolveChildren(view).then(() => {
views.forEach((view) => {
this.resolveChildren(view).then(() => {
views.forEach((view) => {
this.resolveChildren(view).then(() => {
clearTimeout(updateTimer);
updateTimer = setTimeout(() => {
this.handleFormState();
}, 10);
}, noop);
});
}, noop);
});
}, noop);
});
}, noop);
}

private resolveChildren(view) {
return new Promise((resolve, reject) => {
if (!view || !view.children_views) {
reject();
}

view.children_views.update(view.model.get('children'))
.then(views => resolve(views));
});
}
}

export default {
SparkConfigurationModel,
Expand Down
55 changes: 47 additions & 8 deletions js/notebook/src/SparkUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class SparkUIView extends widgets.VBoxView {
private sparkUiWebUrl: string;
private sparkMasterUrl: string;
private apiCallIntervalId: Timer;
private toolbarStatusContainer: HTMLElement|null;
private connectionLabelActive: HTMLElement;
private connectionLabelMemory: HTMLElement;
private connectionLabelDead: HTMLElement;
Expand Down Expand Up @@ -90,6 +91,32 @@ export class SparkUIView extends widgets.VBoxView {
window.open(`${this.sparkUiWebUrl}/executors`, '_blank');
}

private handleFormState() {
const startButton = this.el.querySelector('.bx-spark-connect');

if (this.el.querySelector('.bx-status-panel')) {
this.setFormReadonly(startButton);
} else {
this.setFormEditable(startButton);
}
}

private setFormReadonly(startButton) {
this.masterUrlInput && this.masterUrlInput.setAttribute('readonly', 'readonly');
this.executorCoresInput && this.executorCoresInput.setAttribute('readonly', 'readonly');
this.executorMemoryInput && this.executorMemoryInput.setAttribute('readonly', 'readonly');

startButton && startButton.setAttribute('disabled', 'disabled');
}

private setFormEditable(startButton) {
this.masterUrlInput && this.masterUrlInput.removeAttribute('readonly');
this.executorCoresInput && this.executorCoresInput.removeAttribute('readonly');
this.executorMemoryInput && this.executorMemoryInput.removeAttribute('readonly');

startButton && startButton.removeAttribute('disabled');
}

private addSparkUrls() {
if (!this.connectionStatusElement) {
this.connectionStatusElement = this.el.querySelector('.bx-connection-status');
Expand Down Expand Up @@ -153,18 +180,25 @@ export class SparkUIView extends widgets.VBoxView {

private updateChildren() {
const noop = () => {};
let updateTimer: Timer;

this.resolveChildren(this).then((views) => {
views.forEach((view) => {
this.resolveChildren(view).then((views) => {
views.forEach((view) => {
this.resolveChildren(view)
.then((views) => {
this.handleLocalMasterUrl();
this.toolbarSparkConnectionStatus.append();
this.addSparkUrls();
})
.catch(noop);
views.forEach((view) => {
clearTimeout(updateTimer);
updateTimer = setTimeout(() => {
this.handleLocalMasterUrl();
this.toolbarSparkConnectionStatus.append();
this.addSparkUrls();
this.handleFormState();
this.toggleExecutorConfigInputs();
}, 10);
});
}, noop);
});
}, noop);
});
Expand Down Expand Up @@ -281,14 +315,19 @@ export class SparkUIView extends widgets.VBoxView {
}

private addSparkMetricsWidget() {
let updateTimer: Timer;

this.children_views.update(this.model.get('children')).then((views) => {
views.forEach((view: any) => {
view.children_views.update(view.model.get('children')).then((views) => {
views.forEach((view) => {
if (view instanceof widgets.LabelView && view.el.classList.contains('bx-connection-status')) {
this.createSparkMetricsWidget();
this.toolbarSparkConnectionStatus.append();
this.addSparkUrls();
clearTimeout(updateTimer);
updateTimer = setTimeout(() => {
this.createSparkMetricsWidget();
this.toolbarSparkConnectionStatus.append();
this.addSparkUrls();
}, 10);
}
});
});
Expand Down
10 changes: 10 additions & 0 deletions kernel/base/src/main/java/com/twosigma/beakerx/widget/Box.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ public void add(Widget widget) {
updateChildren();
}

public void add(int index, Widget widget) {
this.children.add(index, widget);
updateChildren();
}

public void add(int index, Widget widget, Message parent) {
this.children.add(index, widget);
updateChildren(parent);
}

public void removeAllChildren() {
List<Widget> ch = new ArrayList<>(getChildren());
ch.forEach(this::remove);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public class SparkConfiguration extends VBox {
this.header = new HBox(asList(this.add, sparkVersionWidget(sparkVersion)));
List<PropertyItem> propertyItems = createPropertyItems(advancedSettings);
this.properties = new PropertiesWidget(propertyItems);
add(new VBox(asList(this.header, this.properties.getWidget())));
VBox configuration = new VBox(asList(this.header, this.properties.getWidget()));
configuration.setDomClasses(new ArrayList<>(asList("bx-spark-configuration")));
add(configuration);
}

private HTML sparkVersionWidget(String version) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,19 @@ private SparkSession getSparkSession() {
}

private void applicationStart() {
clearSparkUIFormPanel();
this.statusPanel = new SparkUIStatus(message -> getSparkSession().sparkContext().stop());
add(this.statusPanel);
this.sparkUIForm.setDomClasses(new ArrayList<>(asList("bx-disabled")));
add(0, this.statusPanel);
sendUpdate(SPARK_APP_ID, sparkEngine.getSparkAppId());
sendUpdate("sparkUiWebUrl", sparkEngine.getSparkUiWebUrl());
sendUpdate("sparkMasterUrl", sparkEngine.getSparkMasterUrl());
}

@Override
public void applicationEnd() {
this.sparkUIForm.setDomClasses(new ArrayList<>());
removeStatusPanel();
singleSparkSession.inActive();
addSparkUIFormPanel();
}

private void removeStatusPanel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ private Text createMasterURL() {
private Button createConnectButton() {
Button connect = new Button();
connect.setDescription(CONNECT);
connect.setDomClasses(new ArrayList<>(asList("bx-spark-connect")));
connect.registerOnClick((content, message) -> onStartAction.run(message));
return connect;
}
Expand Down

0 comments on commit 6d2ab65

Please sign in to comment.