Repository: zeppelin Updated Branches: refs/heads/master 61f4ce894 -> f71d09ca1
ZEPPELIN-1254 Make get and save Interpreter bindings calls via websocket ### What is this PR for? This PR uses websocket to get and save interpreter bindings instead of rest api ### What type of PR is it? Improvement ### Todos * [ ] - Task ### What is the Jira issue? https://issues.apache.org/jira/browse/ZEPPELIN-1254 ### How should this be tested? Go to interpreter binding settings on notebook page and enable/disable interpreter or reorder and save. Simultaneously verify the network calls on browser's console. ### Screenshots (if appropriate) n/a ### Questions: * Does the licenses files need update? n/a * Is there breaking changes for older versions? n/a * Does this needs documentation? n/a Author: Renjith Kamath <[email protected]> Closes #1247 from r-kamath/ZEPPELIN-1254 and squashes the following commits: 6ac1748 [Renjith Kamath] ZEPPELIN-1254 revert indentation 55d95ec [Renjith Kamath] ZEPPELIN-1254 review fix ab0bced [Renjith Kamath] ZEPPELIN-1254 boradcast after updating the interpreter bindings 299bb51 [Renjith Kamath] ZEPPELIN-1254 review fix 97bfd7d [Renjith Kamath] ZEPPELIN-1254 Make get and save Interpreter bindings calls via websocket Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/f71d09ca Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/f71d09ca Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/f71d09ca Branch: refs/heads/master Commit: f71d09ca1f24cf4c767c08b5fc357c4f556d7f1d Parents: 61f4ce8 Author: Renjith Kamath <[email protected]> Authored: Wed Aug 3 17:55:12 2016 +0530 Committer: Jongyoul Lee <[email protected]> Committed: Mon Aug 8 15:00:03 2016 +0900 ---------------------------------------------------------------------- .../apache/zeppelin/rest/NotebookRestApi.java | 31 ++-------- .../InterpreterSettingListForNoteBind.java | 40 ------------- .../apache/zeppelin/socket/NotebookServer.java | 59 ++++++++++++++++---- .../zeppelin/types/InterpreterSettingsList.java | 40 +++++++++++++ .../zeppelin/utils/InterpreterBindingUtils.java | 58 +++++++++++++++++++ .../src/app/notebook/notebook.controller.js | 38 ++++--------- .../websocketEvents/websocketEvents.factory.js | 2 + .../websocketEvents/websocketMsg.service.js | 9 +++ zeppelin-web/test/spec/controllers/notebook.js | 3 +- .../zeppelin/notebook/socket/Message.java | 8 ++- 10 files changed, 181 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java index 700fe1a..f33bef1 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java @@ -20,7 +20,6 @@ package org.apache.zeppelin.rest; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,18 +38,18 @@ import com.google.common.collect.Sets; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import org.apache.commons.lang3.StringUtils; +import org.apache.zeppelin.utils.InterpreterBindingUtils; import org.quartz.CronExpression; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.zeppelin.annotation.ZeppelinApi; -import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.notebook.Note; import org.apache.zeppelin.notebook.Notebook; import org.apache.zeppelin.notebook.NotebookAuthorization; import org.apache.zeppelin.notebook.Paragraph; import org.apache.zeppelin.rest.message.CronRequest; -import org.apache.zeppelin.rest.message.InterpreterSettingListForNoteBind; +import org.apache.zeppelin.types.InterpreterSettingsList; import org.apache.zeppelin.rest.message.NewNotebookRequest; import org.apache.zeppelin.rest.message.NewParagraphRequest; import org.apache.zeppelin.rest.message.RunParagraphWithParametersRequest; @@ -186,29 +185,9 @@ public class NotebookRestApi { @Path("interpreter/bind/{noteId}") @ZeppelinApi public Response bind(@PathParam("noteId") String noteId) { - List<InterpreterSettingListForNoteBind> settingList = new LinkedList<>(); - - List<InterpreterSetting> selectedSettings = notebook.getBindedInterpreterSettings(noteId); - for (InterpreterSetting setting : selectedSettings) { - settingList.add(new InterpreterSettingListForNoteBind(setting.getId(), setting.getName(), - setting.getInterpreterInfos(), true)); - } - - List<InterpreterSetting> availableSettings = notebook.getInterpreterFactory().get(); - for (InterpreterSetting setting : availableSettings) { - boolean selected = false; - for (InterpreterSetting selectedSetting : selectedSettings) { - if (selectedSetting.getId().equals(setting.getId())) { - selected = true; - break; - } - } - - if (!selected) { - settingList.add(new InterpreterSettingListForNoteBind(setting.getId(), setting.getName(), - setting.getInterpreterInfos(), false)); - } - } + List<InterpreterSettingsList> settingList = + InterpreterBindingUtils.getInterpreterBindings(notebook, noteId); + notebookServer.broadcastInterpreterBindings(noteId, settingList); return new JsonResponse<>(Status.OK, "", settingList).build(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/InterpreterSettingListForNoteBind.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/InterpreterSettingListForNoteBind.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/InterpreterSettingListForNoteBind.java deleted file mode 100644 index 6ec5a54..0000000 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/InterpreterSettingListForNoteBind.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.rest.message; - -import java.util.List; - -import org.apache.zeppelin.interpreter.InterpreterInfo; - -/** - * InterpreterSetting information for binding - */ -public class InterpreterSettingListForNoteBind { - private String id; - private String name; - private boolean selected; - private List<InterpreterInfo> interpreters; - - public InterpreterSettingListForNoteBind(String id, String name, - List<InterpreterInfo> interpreters, boolean selected) { - this.id = id; - this.name = name; - this.interpreters = interpreters; - this.selected = selected; - } -} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java index 0f8ce70..00971ad 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java @@ -16,19 +16,10 @@ */ package org.apache.zeppelin.socket; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.servlet.http.HttpServletRequest; - import com.google.common.base.Strings; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; - import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars; import org.apache.zeppelin.display.AngularObject; @@ -37,13 +28,12 @@ import org.apache.zeppelin.display.AngularObjectRegistryListener; import org.apache.zeppelin.helium.ApplicationEventListener; import org.apache.zeppelin.helium.HeliumPackage; import org.apache.zeppelin.interpreter.InterpreterGroup; -import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; -import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; -import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.interpreter.InterpreterOutput; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.InterpreterSetting; +import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry; import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener; +import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; import org.apache.zeppelin.notebook.*; import org.apache.zeppelin.notebook.repo.NotebookRepo; import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision; @@ -53,6 +43,9 @@ import org.apache.zeppelin.scheduler.Job; import org.apache.zeppelin.scheduler.Job.Status; import org.apache.zeppelin.server.ZeppelinServer; import org.apache.zeppelin.ticket.TicketContainer; +import org.apache.zeppelin.types.InterpreterSettingsList; +import org.apache.zeppelin.user.AuthenticationInfo; +import org.apache.zeppelin.utils.InterpreterBindingUtils; import org.apache.zeppelin.utils.SecurityUtils; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; @@ -60,6 +53,13 @@ import org.quartz.SchedulerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; + /** * Zeppelin websocket service. */ @@ -234,6 +234,12 @@ public class NotebookServer extends WebSocketServlet implements case LIST_UPDATE_NOTEBOOK_JOBS: unicastUpdateNotebookJobInfo(conn, messagereceived); break; + case GET_INTERPRETER_BINDINGS: + getInterpreterBindings(conn, messagereceived); + break; + case SAVE_INTERPRETER_BINDINGS: + saveInterpreterBindings(conn, messagereceived); + break; default: break; } @@ -411,6 +417,29 @@ public class NotebookServer extends WebSocketServlet implements .put("notebookRunningJobs", response))); } + public void saveInterpreterBindings(NotebookSocket conn, Message fromMessage) { + String noteId = (String) fromMessage.data.get("noteID"); + try { + List<String> settingIdList = gson.fromJson(String.valueOf( + fromMessage.data.get("selectedSettingIds")), new TypeToken<ArrayList<String>>() { + }.getType()); + notebook().bindInterpretersToNote(noteId, settingIdList); + broadcastInterpreterBindings(noteId, + InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId)); + } catch (Exception e) { + LOG.error("Error while saving interpreter bindings", e); + } + } + + public void getInterpreterBindings(NotebookSocket conn, Message fromMessage) + throws IOException { + String noteID = (String) fromMessage.data.get("noteID"); + List<InterpreterSettingsList> settingList = + InterpreterBindingUtils.getInterpreterBindings(notebook(), noteID); + conn.send(serializeMessage(new Message(OP.INTERPRETER_BINDINGS) + .put("interpreterBindings", settingList))); + } + public List<Map<String, String>> generateNotebooksInfo(boolean needsReload, AuthenticationInfo subject) { @@ -450,6 +479,12 @@ public class NotebookServer extends WebSocketServlet implements broadcast(note.id(), new Message(OP.NOTE).put("note", note)); } + public void broadcastInterpreterBindings(String noteId, + List settingList) { + broadcast(noteId, new Message(OP.INTERPRETER_BINDINGS) + .put("interpreterBindings", settingList)); + } + public void broadcastNoteList(AuthenticationInfo subject) { List<Map<String, String>> notesInfo = generateNotebooksInfo(false, subject); broadcastAll(new Message(OP.NOTES_INFO).put("notes", notesInfo)); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java b/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java new file mode 100644 index 0000000..e016916 --- /dev/null +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java @@ -0,0 +1,40 @@ +/* + * 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.types; + +import java.util.List; + +import org.apache.zeppelin.interpreter.InterpreterInfo; + +/** + * InterpreterSetting information for binding + */ +public class InterpreterSettingsList { + private String id; + private String name; + private boolean selected; + private List<InterpreterInfo> interpreters; + + public InterpreterSettingsList(String id, String name, + List<InterpreterInfo> interpreters, boolean selected) { + this.id = id; + this.name = name; + this.interpreters = interpreters; + this.selected = selected; + } +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java new file mode 100644 index 0000000..9333afd --- /dev/null +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java @@ -0,0 +1,58 @@ +/* + * 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.utils; + +import org.apache.zeppelin.interpreter.InterpreterSetting; +import org.apache.zeppelin.notebook.Notebook; +import org.apache.zeppelin.types.InterpreterSettingsList; + +import java.util.LinkedList; +import java.util.List; + +/** + * Utils for interpreter bindings + */ +public class InterpreterBindingUtils { + public static List<InterpreterSettingsList> getInterpreterBindings(Notebook notebook, + String noteId) { + List<InterpreterSettingsList> settingList = new LinkedList<>(); + List<InterpreterSetting> selectedSettings = + notebook.getBindedInterpreterSettings(noteId); + for (InterpreterSetting setting : selectedSettings) { + settingList.add(new InterpreterSettingsList(setting.getId(), setting.getName(), + setting.getInterpreterInfos(), true)); + } + + List<InterpreterSetting> availableSettings = notebook.getInterpreterFactory().get(); + for (InterpreterSetting setting : availableSettings) { + boolean selected = false; + for (InterpreterSetting selectedSetting : selectedSettings) { + if (selectedSetting.getId().equals(setting.getId())) { + selected = true; + break; + } + } + + if (!selected) { + settingList.add(new InterpreterSettingsList(setting.getId(), setting.getName(), + setting.getInterpreterInfos(), false)); + } + } + + return settingList; + } +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-web/src/app/notebook/notebook.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 1d5e826..7cc7fd9 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -438,23 +438,14 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro } }; - var getInterpreterBindings = function(callback) { - $http.get(baseUrlSrv.getRestApiBase() + '/notebook/interpreter/bind/' + $scope.note.id). - success(function(data, status, headers, config) { - $scope.interpreterBindings = data.body; - $scope.interpreterBindingsOrig = angular.copy($scope.interpreterBindings); // to check dirty - if (callback) { - callback(); - } - }). - error(function(data, status, headers, config) { - if (status !== 0) { - console.log('Error %o %o', status, data.message); - } - }); + var getInterpreterBindings = function() { + websocketMsgSrv.getInterpreterBindings($scope.note.id); }; - var getInterpreterBindingsCallBack = function() { + $scope.$on('interpreterBindings', function(event, data) { + $scope.interpreterBindings = data.interpreterBindings; + $scope.interpreterBindingsOrig = angular.copy($scope.interpreterBindings); // to check dirty + var selected = false; var key; var setting; @@ -479,7 +470,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro } $scope.showSetting = true; } - }; + }); $scope.interpreterSelectionListeners = { accept: function(sourceItemHandleScope, destSortableScope) {return true;}, @@ -519,16 +510,9 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro selectedSettingIds.push(setting.id); } } - - $http.put(baseUrlSrv.getRestApiBase() + '/notebook/interpreter/bind/' + $scope.note.id, - selectedSettingIds). - success(function(data, status, headers, config) { - console.log('Interpreter binding %o saved', selectedSettingIds); - $scope.showSetting = false; - }). - error(function(data, status, headers, config) { - console.log('Error %o %o', status, data.message); - }); + websocketMsgSrv.saveInterpreterBindings($scope.note.id, selectedSettingIds); + console.log('Interpreter bindings %o saved', selectedSettingIds); + $scope.showSetting = false; }; $scope.toggleSetting = function() { @@ -838,7 +822,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro } initializeLookAndFeel(); //open interpreter binding setting when there're none selected - getInterpreterBindings(getInterpreterBindingsCallBack); + getInterpreterBindings(); }); $scope.$on('$destroy', function() { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js index 7657137..e4f45db 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js +++ b/zeppelin-web/src/components/websocketEvents/websocketEvents.factory.js @@ -113,6 +113,8 @@ angular.module('zeppelinWebApp').factory('websocketEvents', $rootScope.$broadcast('listRevisionHistory', data); } else if (op === 'NOTE_REVISION') { $rootScope.$broadcast('noteRevision', data); + } else if (op === 'INTERPRETER_BINDINGS') { + $rootScope.$broadcast('interpreterBindings', data); } }); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js index a4f7802..0e4034c 100644 --- a/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js +++ b/zeppelin-web/src/components/websocketEvents/websocketMsg.service.js @@ -196,6 +196,15 @@ angular.module('zeppelinWebApp').service('websocketMsgSrv', function($rootScope, unsubscribeJobManager: function() { websocketEvents.sendNewEvent({op: 'UNSUBSCRIBE_JOBMANAGER'}); + }, + + getInterpreterBindings: function(noteID) { + websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_BINDINGS', data: {noteID: noteID}}); + }, + + saveInterpreterBindings: function(noteID, selectedSettingIds) { + websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS', + data: {noteID: noteID, selectedSettingIds: selectedSettingIds}}); } }; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-web/test/spec/controllers/notebook.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/test/spec/controllers/notebook.js b/zeppelin-web/test/spec/controllers/notebook.js index 502273f..0b21cc0 100644 --- a/zeppelin-web/test/spec/controllers/notebook.js +++ b/zeppelin-web/test/spec/controllers/notebook.js @@ -7,7 +7,8 @@ describe('Controller: NotebookCtrl', function() { var websocketMsgSrvMock = { getNotebook: function() {}, - listRevisionHistory: function() {} + listRevisionHistory: function() {}, + getInterpreterBindings: function() {} }; var baseUrlSrvMock = { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/f71d09ca/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java ---------------------------------------------------------------------- diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java index e2f5fe9..e91dfbb 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java @@ -127,8 +127,14 @@ public class Message { APP_STATUS_CHANGE, // [s-c] on app status change LIST_NOTEBOOK_JOBS, // [c-s] get notebook job management infomations - LIST_UPDATE_NOTEBOOK_JOBS // [c-s] get job management informations for until unixtime + LIST_UPDATE_NOTEBOOK_JOBS, // [c-s] get job management informations for until unixtime // @param unixTime + GET_INTERPRETER_BINDINGS, // [c-s] get interpreter bindings + // @param noteID + SAVE_INTERPRETER_BINDINGS, // [c-s] save interpreter bindings + // @param noteID + // @param selectedSettingIds + INTERPRETER_BINDINGS // [s-c] interpreter bindings } public OP op;
