Преглед изворни кода

Merge pull request #281 from sharelatex/stop-compile

add support for stopping compile
Brian Gough пре 10 година
родитељ
комит
a3c97533ae

+ 7 - 0
services/web/app/coffee/Features/Compile/ClsiManager.coffee

@@ -36,6 +36,13 @@ module.exports = ClsiManager =
 					outputFiles = ClsiManager._parseOutputFiles(project_id, response?.compile?.outputFiles)
 					callback(null, response?.compile?.status, outputFiles, clsiServerId)
 
+	stopCompile: (project_id, user_id, options, callback = (error) ->) ->
+		compilerUrl = @_getCompilerUrl(options?.compileGroup, project_id, user_id, "compile/stop")
+		opts =
+			url:compilerUrl
+			method:"POST"
+		ClsiManager._makeRequest project_id, opts, callback
+
 	deleteAuxFiles: (project_id, user_id, options, callback = (error) ->) ->
 		compilerUrl = @_getCompilerUrl(options?.compileGroup, project_id, user_id)
 		opts =

+ 9 - 0
services/web/app/coffee/Features/Compile/CompileController.coffee

@@ -41,6 +41,15 @@ module.exports = CompileController =
 					validationProblems:validationProblems
 				}
 
+	stopCompile: (req, res, next = (error) ->) ->
+		project_id = req.params.Project_id
+		AuthenticationController.getLoggedInUserId req, (error, user_id) ->
+			return next(error) if error?
+			logger.log {project_id:project_id, user_id:user_id}, "stop compile request"
+			CompileManager.stopCompile project_id, user_id, (error) ->
+				return next(error) if error?
+				res.status(200).send()
+
 	_compileAsUser: (req, callback) ->
 		# callback with user_id if per-user, undefined otherwise
 		if not Settings.disablePerUserCompiles

+ 6 - 0
services/web/app/coffee/Features/Compile/CompileManager.coffee

@@ -44,6 +44,12 @@ module.exports = CompileManager =
 								logger.log files: outputFiles, "output files"
 								callback(null, status, outputFiles, clsiServerId, limits, validationProblems)
 								
+
+	stopCompile: (project_id, user_id, callback = (error) ->) ->
+		CompileManager.getProjectCompileLimits project_id, (error, limits) ->
+			return callback(error) if error?
+			ClsiManager.stopCompile project_id, user_id, limits, callback
+
 	deleteAuxFiles: (project_id, user_id, callback = (error) ->) ->
 		CompileManager.getProjectCompileLimits project_id, (error, limits) ->
 			return callback(error) if error?

+ 13 - 0
services/web/app/coffee/router.coffee

@@ -105,6 +105,8 @@ module.exports = class Router
 		webRouter.post '/project/:Project_id/settings/admin', AuthorizationMiddlewear.ensureUserCanAdminProject, ProjectController.updateProjectAdminSettings
 
 		webRouter.post '/project/:Project_id/compile', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.compile
+		webRouter.post '/project/:Project_id/compile/stop', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.stopCompile
+
 		# Used by the web download buttons, adds filename header
 		webRouter.get  '/project/:Project_id/output/output.pdf', AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.downloadPdf
 		# Used by the pdf viewers
@@ -127,6 +129,17 @@ module.exports = class Router
 				next()
 			), AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.getFileFromClsi
 
+		# direct url access to output files for user but no build, to retrieve files when build fails
+		webRouter.get  /^\/project\/([^\/]*)\/user\/([0-9a-f-]+)\/output\/(.*)$/,
+			((req, res, next) ->
+				params =
+					"Project_id": req.params[0]
+					"user_id":   req.params[1]
+					"file":       req.params[2]
+				req.params = params
+				next()
+			), AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.getFileFromClsi
+
 		# direct url access to output files for a specific user and build (query string not required)
 		webRouter.get  /^\/project\/([^\/]*)\/user\/([0-9a-f]+)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
 			((req, res, next) ->

+ 13 - 1
services/web/app/views/project/editor/pdf.jade

@@ -36,6 +36,14 @@ div.full-size.pdf(ng-controller="PdfController")
 						i.fa.fa-fw(ng-class="{'fa-check': draft}")
 						|  #{translate("fast")} 
 						span.subdued [draft]
+		a(
+			href
+			ng-click="stop()"
+			ng-show="pdf.compiling",
+			tooltip="#{translate('stop_compile')}"
+			tooltip-placement="bottom"
+		)
+			i.fa.fa-stop()
 		a.log-btn(
 			href
 			ng-click="toggleLogs()"
@@ -239,7 +247,11 @@ div.full-size.pdf(ng-controller="PdfController")
 			.alert.alert-danger(ng-show="pdf.tooRecentlyCompiled")
 				strong #{translate("server_error")} 
 				span #{translate("too_recently_compiled")}
-	
+
+			.alert.alert-danger(ng-show="pdf.compileTerminated")
+				strong #{translate("terminated")}. 
+				span #{translate("compile_terminated_by_user")}
+
 			.alert.alert-danger(ng-show="pdf.timedout")
 				p
 					strong #{translate("timedout")}. 

+ 18 - 0
services/web/public/coffee/ide/pdf/controllers/PdfController.coffee

@@ -94,6 +94,7 @@ define [
 			$scope.pdf.tooRecentlyCompiled = false
 			$scope.pdf.renderingError = false
 			$scope.pdf.projectTooLarge = false
+			$scope.pdf.compileTerminated = false
 
 			# make a cache to look up files by name
 			fileByPath = {}
@@ -104,6 +105,11 @@ define [
 			if response.status == "timedout"
 				$scope.pdf.view = 'errors'
 				$scope.pdf.timedout = true
+				fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
+			else if response.status == "terminated"
+				$scope.pdf.view = 'errors'
+				$scope.pdf.compileTerminated = true
+				fetchLogs(fileByPath['output.log'], fileByPath['output.blg'])
 			else if response.status == "autocompile-backoff"
 				$scope.pdf.view = 'uncompiled'
 			else if response.status == "project-too-large"
@@ -294,6 +300,18 @@ define [
 		ide.$scope.recompileViaKey = () ->
 			$scope.recompile { keyShortcut: true }
 
+		$scope.stop = () ->
+			return if !$scope.pdf.compiling
+
+			$http {
+				url: "/project/#{$scope.project_id}/compile/stop"
+				method: "POST"
+				params:
+					clsiserverid:ide.clsiServerId
+				headers:
+					"X-Csrf-Token": window.csrfToken
+			}
+
 		$scope.clearCache = () ->
 			$http {
 				url: "/project/#{$scope.project_id}/output"