mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Angular object update for helium app
This commit is contained in:
parent
6223cd44d9
commit
16f68871da
7 changed files with 175 additions and 25 deletions
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.zeppelin.helium;
|
||||
|
||||
import org.apache.zeppelin.display.AngularObjectRegistry;
|
||||
import org.apache.zeppelin.interpreter.InterpreterOutput;
|
||||
|
||||
/**
|
||||
|
|
@ -24,11 +25,16 @@ import org.apache.zeppelin.interpreter.InterpreterOutput;
|
|||
public class ApplicationContext {
|
||||
private final String noteId;
|
||||
private final String paragraphId;
|
||||
private final HeliumAppAngularObjectRegistry angularObjectRegistry;
|
||||
public final InterpreterOutput out;
|
||||
|
||||
public ApplicationContext(String noteId, String paragraphId, InterpreterOutput out) {
|
||||
public ApplicationContext(String noteId,
|
||||
String paragraphId,
|
||||
HeliumAppAngularObjectRegistry angularObjectRegistry,
|
||||
InterpreterOutput out) {
|
||||
this.noteId = noteId;
|
||||
this.paragraphId = paragraphId;
|
||||
this.angularObjectRegistry = angularObjectRegistry;
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
|
|
@ -39,4 +45,8 @@ public class ApplicationContext {
|
|||
public String getParagraphId() {
|
||||
return paragraphId;
|
||||
}
|
||||
|
||||
public HeliumAppAngularObjectRegistry getAngularObjectRegistry() {
|
||||
return angularObjectRegistry;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.zeppelin.helium;
|
||||
|
||||
import org.apache.zeppelin.display.AngularObject;
|
||||
import org.apache.zeppelin.display.AngularObjectRegistry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Angular Registry for helium app
|
||||
*/
|
||||
public class HeliumAppAngularObjectRegistry {
|
||||
private final String noteId;
|
||||
private final String appId;
|
||||
private final AngularObjectRegistry angularObjectRegistry;
|
||||
|
||||
public HeliumAppAngularObjectRegistry(AngularObjectRegistry angularObjectRegistry,
|
||||
String noteId,
|
||||
String appId) {
|
||||
this.angularObjectRegistry = angularObjectRegistry;
|
||||
this.noteId = noteId;
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public AngularObject add(String name, Object o) {
|
||||
return angularObjectRegistry.add(name, o, noteId, appId);
|
||||
}
|
||||
|
||||
public AngularObject remove(String name) {
|
||||
return angularObjectRegistry.remove(name, noteId, appId);
|
||||
}
|
||||
|
||||
public AngularObject get(String name) {
|
||||
return angularObjectRegistry.get(name, noteId, appId);
|
||||
}
|
||||
|
||||
public List<AngularObject> getAll() {
|
||||
return angularObjectRegistry.getAll(noteId, appId);
|
||||
}
|
||||
}
|
||||
|
|
@ -725,7 +725,11 @@ public class RemoteInterpreterServer
|
|||
private ApplicationContext getApplicationContext(
|
||||
HeliumPackage packageInfo, String noteId, String paragraphId, String applicationInstanceId) {
|
||||
InterpreterOutput out = createAppOutput(noteId, paragraphId, applicationInstanceId);
|
||||
return new ApplicationContext(noteId, paragraphId, out);
|
||||
return new ApplicationContext(
|
||||
noteId,
|
||||
paragraphId,
|
||||
new HeliumAppAngularObjectRegistry(angularObjectRegistry, noteId, applicationInstanceId),
|
||||
out);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public class ApplicationLoaderTest {
|
|||
ApplicationContext context1 = new ApplicationContext(
|
||||
noteId,
|
||||
paragraphId,
|
||||
null,
|
||||
new InterpreterOutput(new InterpreterOutputListener() {
|
||||
@Override
|
||||
public void onAppend(InterpreterOutput out, byte[] line) {
|
||||
|
|
|
|||
|
|
@ -172,8 +172,23 @@ angular.module('zeppelinWebApp')
|
|||
|
||||
$scope.$on('angularObjectUpdate', function(event, data) {
|
||||
var noteId = $route.current.pathParams.noteId;
|
||||
if (!data.noteId || (data.noteId === noteId && (!data.paragraphId || data.paragraphId === $scope.paragraph.id))) {
|
||||
var scope = paragraphScope;
|
||||
if (!data.noteId || data.noteId === noteId) {
|
||||
var scope;
|
||||
var registry;
|
||||
|
||||
if (!data.paragraphId || data.paragraphId === $scope.paragraph.id) {
|
||||
scope = paragraphScope;
|
||||
registry = angularObjectRegistry;
|
||||
} else {
|
||||
var app = _.find($scope.apps, { id: data.paragraphId})
|
||||
if (app) {
|
||||
scope = getAppScope(app);
|
||||
registry = getAppRegistry(app);
|
||||
} else {
|
||||
// no matching app in this paragraph
|
||||
return;
|
||||
}
|
||||
}
|
||||
var varName = data.angularObject.name;
|
||||
|
||||
if (angular.equals(data.angularObject.object, scope[varName])) {
|
||||
|
|
@ -181,32 +196,32 @@ angular.module('zeppelinWebApp')
|
|||
return;
|
||||
}
|
||||
|
||||
if (!angularObjectRegistry[varName]) {
|
||||
angularObjectRegistry[varName] = {
|
||||
if (!registry[varName]) {
|
||||
registry[varName] = {
|
||||
interpreterGroupId : data.interpreterGroupId,
|
||||
noteId : data.noteId,
|
||||
paragraphId : data.paragraphId
|
||||
};
|
||||
} else {
|
||||
angularObjectRegistry[varName].noteId = angularObjectRegistry[varName].noteId || data.noteId;
|
||||
angularObjectRegistry[varName].paragraphId = angularObjectRegistry[varName].paragraphId || data.paragraphId;
|
||||
registry[varName].noteId = registry[varName].noteId || data.noteId;
|
||||
registry[varName].paragraphId = registry[varName].paragraphId || data.paragraphId;
|
||||
}
|
||||
|
||||
angularObjectRegistry[varName].skipEmit = true;
|
||||
registry[varName].skipEmit = true;
|
||||
|
||||
if (!angularObjectRegistry[varName].clearWatcher) {
|
||||
angularObjectRegistry[varName].clearWatcher = scope.$watch(varName, function(newValue, oldValue) {
|
||||
console.log('angular object (paragraph) updated %o %o', varName, angularObjectRegistry[varName]);
|
||||
if (angularObjectRegistry[varName].skipEmit) {
|
||||
angularObjectRegistry[varName].skipEmit = false;
|
||||
if (!registry[varName].clearWatcher) {
|
||||
registry[varName].clearWatcher = scope.$watch(varName, function(newValue, oldValue) {
|
||||
console.log('angular object (paragraph) updated %o %o', varName, registry[varName]);
|
||||
if (registry[varName].skipEmit) {
|
||||
registry[varName].skipEmit = false;
|
||||
return;
|
||||
}
|
||||
websocketMsgSrv.updateAngularObject(
|
||||
angularObjectRegistry[varName].noteId,
|
||||
angularObjectRegistry[varName].paragraphId,
|
||||
registry[varName].noteId,
|
||||
registry[varName].paragraphId,
|
||||
varName,
|
||||
newValue,
|
||||
angularObjectRegistry[varName].interpreterGroupId);
|
||||
registry[varName].interpreterGroupId);
|
||||
});
|
||||
}
|
||||
console.log('angular object (paragraph) created %o', varName);
|
||||
|
|
@ -228,14 +243,30 @@ angular.module('zeppelinWebApp')
|
|||
|
||||
$scope.$on('angularObjectRemove', function(event, data) {
|
||||
var noteId = $route.current.pathParams.noteId;
|
||||
if (!data.noteId || (data.noteId === noteId && (!data.paragraphId || data.paragraphId === $scope.paragraph.id))) {
|
||||
var scope = paragraphScope;
|
||||
if (!data.noteId || data.noteId === noteId) {
|
||||
var scope;
|
||||
var registry;
|
||||
|
||||
if (!data.paragraphId || data.paragraphId === $scope.paragraph.id) {
|
||||
scope = paragraphScope;
|
||||
registry = angularObjectRegistry;
|
||||
} else {
|
||||
var app = _.find($scope.apps, { id: data.paragraphId})
|
||||
if (app) {
|
||||
scope = getAppScope(app);
|
||||
registry = getAppRegistry(app);
|
||||
} else {
|
||||
// no matching app in this paragraph
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var varName = data.name;
|
||||
|
||||
// clear watcher
|
||||
if (angularObjectRegistry[varName]) {
|
||||
angularObjectRegistry[varName].clearWatcher();
|
||||
angularObjectRegistry[varName] = undefined;
|
||||
if (registry[varName]) {
|
||||
registry[varName].clearWatcher();
|
||||
registry[varName] = undefined;
|
||||
}
|
||||
|
||||
// remove scope variable
|
||||
|
|
@ -2254,6 +2285,21 @@ angular.module('zeppelinWebApp')
|
|||
});
|
||||
};
|
||||
|
||||
var getAppScope = function(appState) {
|
||||
if (!appState.scope) {
|
||||
appState.scope = $rootScope.$new(true, $rootScope);
|
||||
}
|
||||
|
||||
return appState.scope;
|
||||
};
|
||||
|
||||
var getAppRegistry = function(appState) {
|
||||
if (!appState.registry) {
|
||||
appState.registry = {};
|
||||
}
|
||||
|
||||
return appState.registry;
|
||||
};
|
||||
|
||||
var renderApp = function(appState) {
|
||||
var retryRenderer = function() {
|
||||
|
|
@ -2263,7 +2309,7 @@ angular.module('zeppelinWebApp')
|
|||
try {
|
||||
console.log('renderApp %o', appState);
|
||||
targetEl.html(appState.output);
|
||||
$compile(targetEl.contents())(paragraphScope);
|
||||
$compile(targetEl.contents())(getAppScope(appState));
|
||||
} catch(err) {
|
||||
console.log('App rendering error %o', err);
|
||||
}
|
||||
|
|
@ -2285,7 +2331,7 @@ angular.module('zeppelinWebApp')
|
|||
|
||||
var targetEl = angular.element(document.getElementById('p' + app.id));
|
||||
targetEl.html(app.output);
|
||||
$compile(targetEl.contents())(paragraphScope);
|
||||
$compile(targetEl.contents())(getAppScope(app));
|
||||
console.log('append app output %o', $scope.apps);
|
||||
}
|
||||
}
|
||||
|
|
@ -2302,7 +2348,7 @@ angular.module('zeppelinWebApp')
|
|||
|
||||
var targetEl = angular.element(document.getElementById('p' + app.id));
|
||||
targetEl.html(app.output);
|
||||
$compile(targetEl.contents())(paragraphScope);
|
||||
$compile(targetEl.contents())(getAppScope(app));
|
||||
console.log('append app output');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,8 +438,25 @@ public class Note implements Serializable, ParagraphJobListener {
|
|||
if (registry instanceof RemoteAngularObjectRegistry) {
|
||||
// remove paragraph scope object
|
||||
((RemoteAngularObjectRegistry) registry).removeAllAndNotifyRemoteProcess(id, paragraphId);
|
||||
|
||||
// remove app scope object
|
||||
List<ApplicationState> appStates = getParagraph(paragraphId).getAllApplicationStates();
|
||||
if (appStates != null) {
|
||||
for (ApplicationState app : appStates) {
|
||||
((RemoteAngularObjectRegistry) registry).removeAllAndNotifyRemoteProcess(
|
||||
id, app.getId());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
registry.removeAll(id, paragraphId);
|
||||
|
||||
// remove app scope object
|
||||
List<ApplicationState> appStates = getParagraph(paragraphId).getAllApplicationStates();
|
||||
if (appStates != null) {
|
||||
for (ApplicationState app : appStates) {
|
||||
registry.removeAll(id, app.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,6 +306,15 @@ public class Notebook implements NoteEventListener {
|
|||
// remove paragraph scope object
|
||||
for (Paragraph p : note.getParagraphs()) {
|
||||
((RemoteAngularObjectRegistry) registry).removeAllAndNotifyRemoteProcess(id, p.getId());
|
||||
|
||||
// remove app scope object
|
||||
List<ApplicationState> appStates = p.getAllApplicationStates();
|
||||
if (appStates != null) {
|
||||
for (ApplicationState app : appStates) {
|
||||
((RemoteAngularObjectRegistry) registry).removeAllAndNotifyRemoteProcess(
|
||||
id, app.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove notebook scope object
|
||||
((RemoteAngularObjectRegistry) registry).removeAllAndNotifyRemoteProcess(id, null);
|
||||
|
|
@ -313,6 +322,14 @@ public class Notebook implements NoteEventListener {
|
|||
// remove paragraph scope object
|
||||
for (Paragraph p : note.getParagraphs()) {
|
||||
registry.removeAll(id, p.getId());
|
||||
|
||||
// remove app scope object
|
||||
List<ApplicationState> appStates = p.getAllApplicationStates();
|
||||
if (appStates != null) {
|
||||
for (ApplicationState app : appStates) {
|
||||
registry.removeAll(id, app.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove notebook scope object
|
||||
registry.removeAll(id, null);
|
||||
|
|
|
|||
Loading…
Reference in a new issue