Nightmare Js Evaluation timed out after multiple evaluations
up vote
1
down vote
favorite
I'm trying to setup an app I've been developing that involves recording an HTML widget (with animations) and turning it into an mp4. Locally it works great. I have Nightmare Js handling the screenshots and FFMPEG converting the screenshots into an mp4, which takes around 90s on my PC.
I'm setting it up in a docker container through a hosting service, and cannot get past this issue. My test script at the moment looks something like this:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
Some environment details:
Ubuntu 18.04.1
Supervisor
Node 8.12.0 (DEBUG=* set)
The issue:
After about 17 loops, Nightmare throws two different errors.
In my nodejs-stderr.log file, I get this
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
Testing with the done() callback or promise in the evaluation didn't change anything, so I kept it simple
In my nodejs-stdout.log file, I get this for every successful loop
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
And then after 17 or so loops, I get:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
And the rest all fail, without the crashed [{},false]
message.
Removing .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
in the loop solves the issue, but I need that otherwise it's just a motionless video! I have tried separate calls (not chaining evaluate and screenshot), putting .wait(200) between stuff, but I can't figure it out or find any help on this issue.
javascript node.js electron nightmare
add a comment |
up vote
1
down vote
favorite
I'm trying to setup an app I've been developing that involves recording an HTML widget (with animations) and turning it into an mp4. Locally it works great. I have Nightmare Js handling the screenshots and FFMPEG converting the screenshots into an mp4, which takes around 90s on my PC.
I'm setting it up in a docker container through a hosting service, and cannot get past this issue. My test script at the moment looks something like this:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
Some environment details:
Ubuntu 18.04.1
Supervisor
Node 8.12.0 (DEBUG=* set)
The issue:
After about 17 loops, Nightmare throws two different errors.
In my nodejs-stderr.log file, I get this
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
Testing with the done() callback or promise in the evaluation didn't change anything, so I kept it simple
In my nodejs-stdout.log file, I get this for every successful loop
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
And then after 17 or so loops, I get:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
And the rest all fail, without the crashed [{},false]
message.
Removing .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
in the loop solves the issue, but I need that otherwise it's just a motionless video! I have tried separate calls (not chaining evaluate and screenshot), putting .wait(200) between stuff, but I can't figure it out or find any help on this issue.
javascript node.js electron nightmare
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm trying to setup an app I've been developing that involves recording an HTML widget (with animations) and turning it into an mp4. Locally it works great. I have Nightmare Js handling the screenshots and FFMPEG converting the screenshots into an mp4, which takes around 90s on my PC.
I'm setting it up in a docker container through a hosting service, and cannot get past this issue. My test script at the moment looks something like this:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
Some environment details:
Ubuntu 18.04.1
Supervisor
Node 8.12.0 (DEBUG=* set)
The issue:
After about 17 loops, Nightmare throws two different errors.
In my nodejs-stderr.log file, I get this
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
Testing with the done() callback or promise in the evaluation didn't change anything, so I kept it simple
In my nodejs-stdout.log file, I get this for every successful loop
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
And then after 17 or so loops, I get:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
And the rest all fail, without the crashed [{},false]
message.
Removing .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
in the loop solves the issue, but I need that otherwise it's just a motionless video! I have tried separate calls (not chaining evaluate and screenshot), putting .wait(200) between stuff, but I can't figure it out or find any help on this issue.
javascript node.js electron nightmare
I'm trying to setup an app I've been developing that involves recording an HTML widget (with animations) and turning it into an mp4. Locally it works great. I have Nightmare Js handling the screenshots and FFMPEG converting the screenshots into an mp4, which takes around 90s on my PC.
I'm setting it up in a docker container through a hosting service, and cannot get past this issue. My test script at the moment looks something like this:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
Some environment details:
Ubuntu 18.04.1
Supervisor
Node 8.12.0 (DEBUG=* set)
The issue:
After about 17 loops, Nightmare throws two different errors.
In my nodejs-stderr.log file, I get this
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
Testing with the done() callback or promise in the evaluation didn't change anything, so I kept it simple
In my nodejs-stdout.log file, I get this for every successful loop
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
And then after 17 or so loops, I get:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
And the rest all fail, without the crashed [{},false]
message.
Removing .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
in the loop solves the issue, but I need that otherwise it's just a motionless video! I have tried separate calls (not chaining evaluate and screenshot), putting .wait(200) between stuff, but I can't figure it out or find any help on this issue.
javascript node.js electron nightmare
javascript node.js electron nightmare
edited yesterday
asked 2 days ago
Aidan
163
163
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Turned out it was the shared memory being too small. I assume when the images were all loaded it exceeded the memory limit and Electron crashed. After upping the shared memory from 64MB to 128MB, the issue is solved.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Turned out it was the shared memory being too small. I assume when the images were all loaded it exceeded the memory limit and Electron crashed. After upping the shared memory from 64MB to 128MB, the issue is solved.
add a comment |
up vote
0
down vote
Turned out it was the shared memory being too small. I assume when the images were all loaded it exceeded the memory limit and Electron crashed. After upping the shared memory from 64MB to 128MB, the issue is solved.
add a comment |
up vote
0
down vote
up vote
0
down vote
Turned out it was the shared memory being too small. I assume when the images were all loaded it exceeded the memory limit and Electron crashed. After upping the shared memory from 64MB to 128MB, the issue is solved.
Turned out it was the shared memory being too small. I assume when the images were all loaded it exceeded the memory limit and Electron crashed. After upping the shared memory from 64MB to 128MB, the issue is solved.
answered yesterday
Aidan
163
163
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372889%2fnightmare-js-evaluation-timed-out-after-multiple-evaluations%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown