1

I am creating a chess engine using nodejs in lambda but due to asynchronous call it showing timeout error on lambda every time. This is just partial part of the function. It is working fine on local nodejs console but not on the lambda. Please someone suggest something as I am new to this.

var chessjs = require('./chess');
var engine = require('uci');
var uciengine = new engine(process.env['LAMBDA_TASK_ROOT'] + '/stockfish');
var fs = require("fs");
var match;

function moveEngine() {
var curfen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
var depth = '20';

uciengine.runProcess().then(
        () => {
    console.log("Started.");
    return uciengine.uciCommand();
}
).then(
        () => {
    console.log("Is Ready?");
    return uciengine.isReadyCommand();
}
).then(
        () => {
    console.log("New game.");
    return uciengine.uciNewGameCommand();
}
).then(
        () => {
    console.log("Setting position.");
    return uciengine.positionCommand(curfen);
}
).then(
        () => {
    console.log('Starting position set');
    console.log('Starting analysis');
    return uciengine.depthLimitedGoCommand(depth, (info) => {
    });
}
).then((bestmove) => {
    console.log('Bestmove: ');
    console.log(bestmove);
    return uciengine.quitCommand();
}).then(() => {
    console.log('Stopped');
   response.sessionAttributes = {};
   context.succeed(response);
}).done();
}

  async call code
var chessjs = require('./chess');
var engine = require('uci');
var async= require('async');
var uciengine = new engine('/var/task/stockfish');
var fs = require("fs");
var match;

function moveEngine() {
   var curfen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
   var depth = '20';

async.auto({
runProcess: function(next, results) {
    uciengine.runProcess(next,results);
},
checkUiEngineReady:['runProcess',function(next,results) {
  uciengine.checkUiEngineReady(next,results);
}],
newGameCommand:['checkUiEngineReady',function(next,results) {
  uciengine.newGameCommand(next,results);
}],
position:['newGameCommand',function(next,results) {
  uciengine.positionCommand(curfen,next,results);
}],
godepth:['position',function(next,results) {
  uciengine.depthLimitedGoCommand(depth,next,results);
}]
}, function(err, response) {
if (err) {
    next(err);
} else {
    console.log(response);
    uciengine.quitCommand();
    context.succeed(response);
}
});
}
moveEngine();

async call is giving the same error like before and i think it is probably wrong.

Exterminator
  • 1,221
  • 7
  • 14
  • Do you need to perhaps call `engine.done()` to close something persisting on the event loop? Or, perhaps you should set `context.callbackWaitsForEmptyEventLoop = false` (but avoid that if possible unless you understand its implications)? – Michael - sqlbot Mar 22 '18 at 14:44
  • tried that but ain't working. Is my syntax for the async function is correct? It is confusing. Thank you for the response. – Exterminator Mar 23 '18 at 05:57

1 Answers1

2

You can handle the Async call in Lambda using async npm module which is a utility module to handle asynchronous programming in Nodejs.

You can install the async module with npm install --save async.

async.auto function will be useful to manage the above call.

Here is an example through which you can manage your code.

async.auto({
    runProcess: function(next, results) {
        runProcess(next,results);
    },
    checkUiEngineReady:['runProcess',function(next,results) {
      checkUiEngineReady(next,results);
    }],
    newGameCommand:['checkUiEngineReady',function(next,results) {
      newGameCommand(next,results);
    }]
}, function(err, response) {
    if (err) {
        next(err);
    } else {
        context.succeed(response);
    }
});

Thanks

Ankit Uniyal
  • 424
  • 1
  • 7
  • 20
  • i already installed async in my modules but first time when i used it i just included var async = require('async'); in my code and it started working but now it ain't working don't know what's wrong now. is my path for the chess engine is correct?? – Exterminator Mar 22 '18 at 08:19
  • Can you show me the error, and also have you set up the timeout time in your Lambda console ? – Ankit Uniyal Mar 22 '18 at 09:37
  • Response: { "errorMessage": "2018-03-22T10:41:08.435Z d48b4ae1-2dbc-11e8-9822-f7bc88c773ee Task timed out after 300.05 seconds" } Request ID: "d48b4ae1-2dbc-11e8-9822-f7bc88c773ee" Function Logs: START RequestId: d48b4ae1-2dbc-11e8-9822-f7bc88c773ee Version: $LATEST END RequestId: d48b4ae1-2dbc-11e8-9822-f7bc88c773ee REPORT RequestId: d48b4ae1-2dbc-11e8-9822-f7bc88c773ee Duration: 300047.20 ms Billed Duration: 300000 ms Memory Size: 128 MB Max Memory Used: 36 MB 2018-03-22T10:41:08.435Z d48b4ae1-2dbc-11e8-9822-f7bc88c773ee Task timed out after 300.05 seconds – Exterminator Mar 22 '18 at 10:44
  • From above logs, it seems that your code execution is taking more than 300 seconds (i.e 5 minutes). Are you using any long running task which is taking more than 5 minutes time and also can you increase your lambda function memory size from AWS lambda console ? – Ankit Uniyal Mar 22 '18 at 11:17
  • no, actually it task take 10 sec at max when i run it locally – Exterminator Mar 22 '18 at 11:31
  • Did you check your logs from cloud watch console, have you ever to identify where it gets blocked using cloud watch logs ? – Ankit Uniyal Mar 22 '18 at 11:44
  • You added above that at first time it works in your lambda and also are you sure you have added the correct required path for var chessjs = require('./chess'); as isn't it should be var chessjs = require('./chess.js'); – Ankit Uniyal Mar 22 '18 at 12:00
  • that is working fine. i tried it with other method and it is working fine on local as well – Exterminator Mar 22 '18 at 12:07
  • i mean that var chessjs = require('./chess'); is not creating any problem. main problem are those async calls – Exterminator Mar 22 '18 at 12:14
  • did you try with async npm module with async.auto method and if yes then please share your code ? – Ankit Uniyal Mar 22 '18 at 12:19
  • Just to know, is your lambda function running inside a VPC ? – Ankit Uniyal Mar 23 '18 at 10:59
  • Ok, so just to make sure that are you returning next function like next(null,true) from each of your functions which you defined in your async.auto function ? – Ankit Uniyal Mar 23 '18 at 11:10
  • Also, is any of your function's console logs showing (added in async.auto method) or it is the timeout showing to you at the starting ? If logs are showing to you then return the response like this below callback(null, { statusCode: 200, body: JSON.stringify(response) }); – Ankit Uniyal Mar 23 '18 at 11:14
  • i updated the exact copy of the async i am using and also it get stuck after .then function. let me try this method for returning response also. i will let you know – Exterminator Mar 23 '18 at 11:22
  • any success on this ? – Ankit Uniyal Mar 23 '18 at 11:56
  • not yet. i tried that as well. please check my async function i created is it correct for the function i had given – Exterminator Mar 26 '18 at 07:47
  • You need to use return value using callback as callback will be used to stop the Lambda function execution. Also, tell me your lambda function handler name which you are exporting that function with module.exports.function_name and the same settings will be mapped on AWS Lambda console. – Ankit Uniyal Mar 26 '18 at 09:28