diff --git a/zeppelin-web/src/app/interpreter/interpreter.controller.js b/zeppelin-web/src/app/interpreter/interpreter.controller.js index ab660330654..ad55aef3aa4 100644 --- a/zeppelin-web/src/app/interpreter/interpreter.controller.js +++ b/zeppelin-web/src/app/interpreter/interpreter.controller.js @@ -14,8 +14,9 @@ */ 'use strict'; -angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $route, $routeParams, $location, $rootScope, - $http, baseUrlSrv, ngToast) { +angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $route, + $routeParams, $location, $rootScope, $http, baseUrlSrv, + ngToast, baseInterpreterService) { var interpreterSettingsTmp = []; $scope.interpreterSettings = []; $scope.availableInterpreters = {}; @@ -23,16 +24,6 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $scope.showRepositoryInfo = false; $scope._ = _; - var getInterpreterSettings = function() { - $http.get(baseUrlSrv.getRestApiBase()+'/interpreter/setting'). - success(function(data, status, headers, config) { - $scope.interpreterSettings = data.body; - }). - error(function(data, status, headers, config) { - console.log('Error %o %o', status, data.message); - }); - }; - var getAvailableInterpreters = function() { $http.get(baseUrlSrv.getRestApiBase()+'/interpreter'). success(function(data, status, headers, config) { @@ -153,14 +144,10 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, message: 'Do you want to restart this interpreter?', callback: function(result) { if (result) { - $http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/restart/' + settingId). - success(function(data, status, headers, config) { - var index = _.findIndex($scope.interpreterSettings, { 'id': settingId }); - $scope.interpreterSettings[index] = data.body; - }). - error(function(data, status, headers, config) { - console.log('Error %o %o', status, data.message); - }); + baseInterpreterService.restartInterpreterSetting(settingId).then(function(interpreterSettings) { + var index = _.findIndex($scope.interpreterSettings, {'id': settingId}); + $scope.interpreterSettings[index] = interpreterSettings; + }); } } }); @@ -202,16 +189,18 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, } request.properties = newProperties; - $http.post(baseUrlSrv.getRestApiBase() + '/interpreter/setting', request). - success(function(data, status, headers, config) { - $scope.resetNewInterpreterSetting(); - getInterpreterSettings(); - $scope.showAddNewSetting = false; - }). - error(function(data, status, headers, config) { - console.log('Error %o %o', status, data.message); - ngToast.danger(data.message); + $http.post(baseUrlSrv.getRestApiBase()+'/interpreter/setting', newSetting). + success(function(data, status, headers, config) { + $scope.resetNewInterpreterSetting(); + baseInterpreterService.getInterpreterSettings().then(function(setting) { + $scope.interpreterSettings = setting; }); + $scope.showAddNewSetting = false; + }). + error(function(data, status, headers, config) { + console.log('Error %o %o', status, data.message); + ngToast.danger(data.message); + }); }; $scope.cancelInterpreterSetting = function() { @@ -399,8 +388,9 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, var init = function() { $scope.resetNewInterpreterSetting(); - $scope.resetNewRepositorySetting(); - getInterpreterSettings(); + baseInterpreterService.getInterpreterSettings().then(function(setting) { + $scope.interpreterSettings = setting; + }); getAvailableInterpreters(); getRepositories(); }; diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 194cd7788ca..49b6518e962 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -16,8 +16,8 @@ 'use strict'; angular.module('zeppelinWebApp').controller('NotebookCtrl', - function($scope, $route, $routeParams, $location, $rootScope, $http, - websocketMsgSrv, baseUrlSrv, $timeout, SaveAsService) { + function($scope, $route, $routeParams, $location, $rootScope, $http, websocketMsgSrv, baseUrlSrv, + $timeout, SaveAsService, baseInterpreterService) { $scope.note = null; $scope.showEditor = false; $scope.editorToggled = false; @@ -694,6 +694,47 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', } }; + $scope.restartInterpreterSetting = function(id) { + var paragraph; + for (var paragraphIndex in $scope.note.paragraphs) { + if ($scope.note.paragraphs[paragraphIndex].id == id) { + paragraph = $scope.note.paragraphs[paragraphIndex]; + } + } + var settingId = ""; + var settingName = ""; + var language; + if (paragraph.text.split('\n')[0][0] === '%') { + language = paragraph.text.split('\n')[0].split(' ')[0].split('.')[0].split('%')[1]; + } + if (language) { + for (var settingIndex in $scope.interpreterBindings) { + if ($scope.interpreterBindings[settingIndex].name === language) { + settingId = $scope.interpreterBindings[settingIndex].id; + settingName = $scope.interpreterBindings[settingIndex].group; + break; + } + } + } else { + settingId = $scope.interpreterBindings[0].id; + settingName = $scope.interpreterBindings[0].group; + } + + BootstrapDialog.confirm({ + title: '', + message: 'Restart ' + settingName + ' interpreter?
Note that all interpreter states and local variables will be reset.
', + callback: function(result) { + if (result) { + $scope.paragraph.interpreterRestarting = true; + + baseInterpreterService.restartInterpreterSetting(settingId).then(function() { + $scope.paragraph.interpreterRestarted = true; + }); + } + } + }); + }; + var isSettingDirty = function() { if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) { diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html index 77d74519795..17e3b025a55 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html @@ -58,4 +58,15 @@ ng-if="paragraph.status == 'ERROR'" ng-bind="paragraph.errorMessage"> + +
+
+ +
+
+ Interpreter restarted successfully, re-run the paragraph. +
+
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 3935cfcd7d5..f1fd04811a4 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -17,6 +17,7 @@ angular.module('zeppelinWebApp') .controller('ParagraphCtrl', function($scope,$rootScope, $route, $window, $element, $routeParams, $location, $timeout, $compile, websocketMsgSrv) { + var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_'; $scope.paragraph = null; $scope.originalText = ''; @@ -347,6 +348,8 @@ angular.module('zeppelinWebApp') $scope.paragraph.status = data.paragraph.status; $scope.paragraph.result = data.paragraph.result; $scope.paragraph.settings = data.paragraph.settings; + $scope.paragraph.interpreterRestarting = undefined; + $scope.paragraph.interpreterRestarted = undefined; if (!$scope.asIframe) { $scope.paragraph.config = data.paragraph.config; @@ -2097,7 +2100,20 @@ angular.module('zeppelinWebApp') $window.open(redirectToUrl); }; - $scope.showScrollDownIcon = function(){ + $scope.checkErrorForRestart = function() { + var errorText = $scope.paragraph.result.msg; + if (errorText) { + errorText = errorText.toLowerCase(); + if (errorText.indexOf('timed out') > 0 || + (errorText.indexOf('thrift') > 0) && errorText.indexOf('except') > 0 || + errorText.indexOf('connection refused') > 0) { + return true; + } + } + return false; + }; + + $scope.showScrollDownIcon = function() { var doc = angular.element('#p' + $scope.paragraph.id + '_text'); if(doc[0]){ return doc[0].scrollHeight > doc.innerHeight(); diff --git a/zeppelin-web/src/components/baseInterpreterService/baseInterpreter.service.js b/zeppelin-web/src/components/baseInterpreterService/baseInterpreter.service.js new file mode 100644 index 00000000000..f6d8bc87049 --- /dev/null +++ b/zeppelin-web/src/components/baseInterpreterService/baseInterpreter.service.js @@ -0,0 +1,45 @@ +/* + * Licensed 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. + */ +'use strict'; + +angular.module('zeppelinWebApp').service('baseInterpreterService', function($http, baseUrlSrv, $q) { + + this.getInterpreterSettings = function() { + return $q(function(resolve, reject) { + $http.get(baseUrlSrv.getRestApiBase() + '/interpreter/setting'). + success(function(data, status, headers, config) { + resolve(data.body); + }). + error(function(data, status, headers, config) { + console.log('Error %o %o', status, data.message); + reject(); + }); + }); + }; + + this.restartInterpreterSetting = function(settingId) { + return $q(function(resolve, reject) { + $http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/restart/' + settingId). + success(function(data, status, headers, config) { + resolve(data.body); + }). + error(function(data, status, headers, config) { + console.log('Error %o %o', status, data.message); + reject(); + }); + }); + + }; + +}); diff --git a/zeppelin-web/src/index.html b/zeppelin-web/src/index.html index 1f1166b1bd5..cdd8d267023 100644 --- a/zeppelin-web/src/index.html +++ b/zeppelin-web/src/index.html @@ -152,6 +152,7 @@ +