Skip to content

Commit 0f9ba99

Browse files
committed
fixing maxBuffer abort
1 parent 755f4f9 commit 0f9ba99

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

docs/_data/help.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,14 @@
240240
description: |
241241
This is not a single variable but rather an infinite amount of variables. You can set as many as you want. The dynamic part is the name of the lib data. For example `YTT_LIB_DATA_MYLIB=values.yml` results in the contents of `values.yml` to be used by ytt in the `mylib` library.
242242
version: 5.0.8
243+
- name: PROCESS_MAX_BUFFER
244+
type: number
245+
allowed: a valid number
246+
short: Maximum buffer size
247+
default: 1024 * 1024
248+
description: |
249+
The maximum buffer size for the process execution. If you have large output, you might want to increase this value.
250+
version: 5.0.8
243251
- name: LOG_LEVEL
244252
type: string
245253
choices:

server/config/app.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var app_config = {
2424
enableBypass: (process.env.ENABLE_BYPASS ?? 0)==1,
2525
enableDbQueryLogging: (process.env.ENABLE_DB_QUERY_LOGGING ?? 0)==1,
2626
enableFormsYamlInDatabase: (process.env.ENABLE_FORMS_YAML_IN_DATABASE ?? 0)==1,
27+
processMaxBuffer: process.env.PROCESS_MAX_BUFFER || (1024 * 1024),
2728
adminUsername: process.env.ADMIN_USERNAME || "admin",
2829
adminPassword: process.env.ADMIN_PASSWORD || "AnsibleForms!123"
2930
};

server/src/controllers/job.controller.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ exports.abortJob = function(req, res) {
1212
res.json(new RestResult("error","You must provide a jobid","",""));
1313
return false
1414
}
15-
Job.abort(jobid)
16-
.then((job)=>{res.json(new RestResult("success","job aborted",null,""))})
17-
.catch((err)=>{res.json(new RestResult("error","failed to abort job",null,err.toString()))})
15+
Job.abort(jobid)
16+
.then((job)=>{res.json(new RestResult("success","job aborted",null,""))})
17+
.catch((err)=>{res.json(new RestResult("error","failed to abort job",null,err.toString()))})
1818
};
1919
exports.getJob = function(req, res) {
2020
var user = req.user.user

server/src/models/job.model.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Exec.executeCommand = (cmd,jobid,counter) => {
5050
var hiddenExtravarsFileName = cmd.hiddenExtravarsFileName
5151
var keepExtravars = cmd.keepExtravars
5252
var task = cmd.task
53+
const ac = new AbortController()
5354

5455
// execute the procces
5556
return new Promise((resolve,reject)=>{
@@ -69,7 +70,13 @@ Exec.executeCommand = (cmd,jobid,counter) => {
6970
logger.warning("No filename was given")
7071
}
7172

72-
var child = exec(command,{cwd:directory,encoding: "UTF-8"});
73+
// adding abort signal
74+
var child = exec(command,{cwd:directory,signal:ac.signal,maxBuffer:appConfig.processMaxBuffer,encoding: "UTF-8"});
75+
76+
// capture the abort event, logging only
77+
ac.signal.addEventListener('abort', (event) => {
78+
logger.warning("Operator aborted the process")
79+
}, { once: true });
7380

7481
// add output eventlistener to the process to save output
7582
child.stdout.on('data',function(data){
@@ -78,8 +85,8 @@ Exec.executeCommand = (cmd,jobid,counter) => {
7885
.then((status)=>{
7986
// if abort request found ; kill the process
8087
if(status=="abort"){
81-
logger.warning("Abort is requested, killing child")
82-
process.kill(child.pid,"SIGTERM");
88+
logger.warning("Abort is requested, aborting child")
89+
ac.abort("Aborted by operator")
8390
}
8491
})
8592
.catch((error)=>{logger.error("Failed to create output : ", error)})
@@ -91,18 +98,27 @@ Exec.executeCommand = (cmd,jobid,counter) => {
9198
.then((status)=>{
9299
// if abort request found ; kill the process
93100
if(status=="abort"){
94-
logger.warning("Abort is requested, killing child")
95-
process.kill(child.pid,"SIGTERM");
101+
logger.warning("Abort is requested, aborting child")
102+
ac.abort("Aborted by operator")
96103
}
97104
})
98105
.catch((error)=>{logger.error("Failed to create output: ", error)})
99106
})
107+
108+
109+
100110
// add exit eventlistener to the process to handle status update
101-
child.on('exit',function(data){
111+
child.on('exit',async function(data){
102112
// if the exit was an actual request ; set aborted
103113
if(child.signalCode=='SIGTERM'){
104-
Job.endJobStatus(jobid,++counter,"stderr","aborted",`${task} was aborted by operator`)
105-
reject(`${task} was aborted by operator`)
114+
const statusResult = await mysql.do("SELECT status FROM AnsibleForms.`jobs` WHERE id=?;", [jobid])
115+
if(statusResult[0].status=="abort"){
116+
Job.endJobStatus(jobid,++counter,"stderr","aborted",`${task} was aborted by the operator`)
117+
reject(`${task} was aborted by the operator`)
118+
}else{
119+
Job.endJobStatus(jobid,++counter,"stderr","failed",`${task} was aborted by the main process. Likely some buffer or memory error occured. Also check the maxBuffer option.`)
120+
reject(`${task} was aborted by the main process`)
121+
}
106122
}else{ // if the exit was natural; set the jobstatus (either success or failed)
107123
if(data!=0){
108124
jobstatus="failed"

0 commit comments

Comments
 (0)