I'm try to create a task on AWS Lambda that create PDF file from PhantomJS then upload it AWS S3 later.
Now, I try to run it on Lambda but it's always Timeout.
My Lambda has 128mb of ram. The runtime is node.js 4.4.3.
This is the error I got from Lambda
"errorMessage": "2017-03-01T08:05:56.255Z dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Task timed out after 10.00 seconds"
Also these are the log output
REPORT RequestId: dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Duration: 10000.08 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 29 MB
2017-03-01T08:05:56.255Z dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Task timed out after 10.00 seconds
This is my code.
Index.js
var childProcess = require('child_process');
var path = require('path');
exports.handler = function(event, context, callback) {
// Set the path as described here: https://aws.amazon.com/blogs/compute/running-executables-in-aws-lambda/
process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'];
// Set the path to the phantomjs binary
var phantomPath = path.join(__dirname, 'phantomjs_linux-x86_64');
// Arguments for the phantom script
var processArgs = [
path.join(__dirname, 'phantom-script.js'),
event.url
];
// Launc the child process
childProcess.execFile(phantomPath, processArgs, function(error, stdout, stderr) {
if (error) {
context.fail(error);
return;
}
if (stderr) {
context.fail(error);
return;
}
context.succeed(stdout);
});
}
phantom-script.js
var system = require('system');
var args = system.args;
// Example of how to get arguments passed from node script
// args[0] would be this file's name: phantom-script.js
const url = "https://google.com";
system.stdout.write('hello from phantom!');
console.log("task start, target url = " + url);
console.time("execute time");
phantom.create().then(function(ph) {
console.time("create Page");
ph.createPage().then(function(page) {
console.timeEnd("create Page");
console.time("open website");
page.open(url).then(function(status) {
console.timeEnd("open website");
console.time("render as pdf");
page.render('google.pdf').then(function() {
console.timeEnd("render as pdf");
console.log('Page Rendered');
ph.exit();
// send to s3
console.timeEnd("execute time");
});
});
});
});
// Send some info node's childProcess' stdout
system.stdout.write('hello from phantom!')
phantom.exit();
I try to do my work following this answer but it's not working.
I didn't get any of log from my phantom-script.js
like it is not trigger but my task always timeout.
After I spend a lot of time on it. I found the package name Phantomjs-Prebuilt that you can install it via npm
. you have to do npm install
on amazon linux instance or docker amazon linux that has node version 4.x (lambda is using node version 4.3). Otherwise it will not work on lambda.
Then, I updated my code like this.
Index.js
var phantomjs = require('phantomjs-prebuilt')
exports.handler = function(event, context, callback) {
var sourceUrl = "https://example.com"
var program = phantomjs.exec('phantom-script.js', sourceUrl)
program.stdout.pipe(process.stdout)
program.stderr.pipe(process.stderr)
program.on('exit', code => {
// do something here after you phantomjs finish.
return
})
}
phantom-script.js
var system = require('system')
var args = system.args
// Example of how to get arguments passed from node script
// args[0] would be this file's name: phantom-script.js
var url = args[1] // received sourceUrl value
// Send some info node's childProcess' stdout
system.stdout.write('phantomJS running\r\n')
var webpage = require('webpage').create()
webpage.paperSize = {
format: 'A4',
orientation: 'landscape'
}
webpage.open(url, function(status) {
system.stdout.write('start open page\r\n')
webpage.render('/tmp/web.pdf', {
format: 'pdf',
quality: '100'
})
system.stdout.write('finish render page\r\n')
phantom.exit()
})
On lambda the place you can write a file is /tmp
folder that why i saved the file there.
I'm running this via lambda with 192mb of ram. It's work really fine. I can create a screenshot of webpage that has 500 images with this setting. The most important thing is make sure your lambda is able to connect internet.
FYI, I realize that when phantom-script.js (the file i wrote phantom script in.) has an error your lambda will freeze until it timeout. That's why I always got this response from lambda Task timed out after 10.00 seconds
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With