简体   繁体   中英

Parsing progress live from console output - NodeJS

Link to a similar problem that has no answers, but written in C

I'm using NodeJS to parse output from ark-server-tools , which is a layer on top of SteamCMD. What I'd like to do is parse the progress of the update and assign it to a variable, which I'll return as a GET call that the client can use to check progress of the update.

I put the log results of an update into a file to run my code against, which I've put in a PasteBin for brevity .

update.js

app.get('/update', function(req, res) {
  var toReturn;
  var outputSoFar;
  var total;
  var startPos;
  var endPos = 0;

  //var proc = spawn('arkmanager', ['update', '--safe']);
  var proc = spawn('./update-log.sh'); //for testing purposes
  proc.stdout.on('data', function(data){
    outputSoFar += data.toString();


    //if server is already updated
    if (outputSoFar.indexOf('Your server is already up to date!') !== -1) {
      toReturn = 'Server is already up-to-date.';
    }

    //find update progress
    if (outputSoFar.indexOf('progress:') !== -1) {
      for(var line in outputSoFar.split('\n')){
        console.log('found progress');
        startPos = outputSoFar[line].indexOf('progress:', endPos) + 10; //get the value right after progress:_, which should be a number
        endPos = outputSoFar[line].indexOf(' (', startPos); // find the end of this value, which is signified by space + (
        console.log(outputSoFar[line].substring(startPos, endPos).trim());
        updatePercent = outputSoFar[line].substring(startPos, endPos).trim(); //returned to the `checkUpdateProgress` endpoint
      }

      toReturn = 'Updating...';
    }
  });

  proc.stderr.on('data', function(data){
    console.log(data);
  });

  proc.on('close', function (code, signal) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write(JSON.stringify(toReturn));
    res.end();
  });
}

/*
 * Returns progress of an update
 */
app.get('/updateProgress', function(req, res){
    console.log('updatePercent: ' + updatePercent);
    res.send(JSON.stringify(updatePercent));
});

Couple questions:

1) Is this the best way to architect my RESTful API? One call for the action of updating and another for checking the progress of the update?

2) I'd love a better way to test the function, as echoing the console log returns the data in one piece, as opposed to a data stream. How do I do this?

3) I'm pretty sure the parsing function itself isn't quite right, but I'm having a hard time testing it because of #2.

If you want to take a look at the project in its entirety, here's the repo . Thanks in advance for your help!

For one of your questions:

Is this the best way to architect my RESTful API? One call for the action of updating and another for checking the progress of the update?

As implemented now, I don't think your service can support concurrent requests correctly. updatePercent is a shared global variable. If i hit /update endpoint with a single client, it will start the ./update-log.sh command.

If I request /update again, it will start another update and overwrite the global updateProgress . There doesn't seem to be anything mapping an updatePercent with the correct process

Additionally, there could be serious performance issues to each request spawning a new process. Node might be able to handle hundreds or thousands of concurrent connections using a single thread, but each request is going to spawn a new process, just something to profile

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM