How can you trigger a throw instruction after a certain time? - node.js

Problem: A library function is called, which sometimes does not work. If this function does not work, it sometimes happens that it does not return an error message but is stuck in an infinite loop.
Idea: My idea now would have been to use a timer, which executes a throw instruction after a given time, if the function has not been completed successfully before.
If the function was successfully completed, before the end of the timer, the timer should simply be closed.
Not working example code:
var errorCounter = 0;
async function a(m) {
try {
var myVar = setTimeout(function () {
throw console.log('Error');
}, 60000);
await libraryFunction(m);
clearTimeout(myVar);
} catch {
errorCounter++;
console.log(errorCounter);
}
}

You could use Promise.race to simulate a timeout (play with the numerical values below):
const timeout = new Promise((_, reject) => {
setTimeout(() => reject(new Error('timeout')), 1000);
});
const task = new Promise((resolve, _) => {
setTimeout(() => resolve('done'), 2000);
});
Promise.race([timeout, task])
.then((result) => { console.log(result); })
.catch((err) => { console.log(err.message); });
So in your case, it would look something like this:
const timeout = new Promise((_, reject) => {
setTimeout(() => reject(new Error('timeout')), 60 * 1000);
});
var errorCounter = 0;
function a(m) {
Promise.race([timeout, libraryFunction(m)])
.then((res) => { console.log(res); })
.catch((err) => {
errorCounter++;
console.log(errorCounter);
});
}

You can use Promise.race for this type of thing:
const MAX_WAIT_TIME = 500
const libFn = new Promise((resolve, reject) => {
setTimeout(() => resolve('success'), Math.random() * 1000);
})
const throwFn = new Promise((resolve, reject) => {
setTimeout(() => reject('failure'), MAX_WAIT_TIME);
})
;(async () => {
const result = await Promise.race([libFn, throwFn])
console.log('done') // this line won't execute if the timeout is reached
})()

Related

Jest - how to mock a Class used by a module?

I have a class :
class RequestTimeout {
constructor(timeoutMilliseconds) {
this.timeoutMilliseconds = timeoutMilliseconds;
this.timeoutID = undefined;
}
start() {
return new Promise((resolve, reject) => {
this.timeoutID = setTimeout(() => reject(new Error(`Request attempt exceeded timeout of ${this.timeoutMilliseconds}`)), this.timeoutMilliseconds);
});
}
clear() {
if (this.timeoutID) clearTimeout(this.timeoutID);
}
}
module.exports = RequestTimeout;
This class is used in a module:
const RequestTimeout = require('./request-timeout');
function Request() {
...
async function withTimeout(request, ms) {
const timeout = new RequestTimeout(ms);
return Promise.race([
request(),
timeout.start(),
])
.then(
response => {
timeout.clear();
return response;
},
err => {
timeout.clear();
throw err;
}
);
}
...
}
How do i mock RequestTimeout in a test using Request? For example:
it('should clear the timeout following a successful response', async () => {
nock('http://example.com')
.get('/')
.reply(200, { example: true });
const response = await request.get({ ...baseOptions });
expect(response.example).toEqual(true);
});
// MOCK
let mockGetTimeOutId = jest.fn();
jest.mock('../request-timeout', () => {
return jest.fn().mockImplementation((ms) => {
let timeoutId = undefined;
return {
start: () => new Promise((resolve, reject) => {
timeoutId = setTimeout(() => reject(), ms);
}),
clear: () => mockGetTimeOutId(timeoutId),
}
})
});
// TEST
it('should clear the timeout following a successful response', async () => {
nock('http://example.com')
.get('/')
.reply(200, { example: true });
expect(mockGetTimeOutId).toHaveBeenCalledTimes(0);
const response = await request.get({ ...baseOptions });
expect(mockGetTimeOutId).toHaveBeenCalledTimes(1);
expect(response.example).toEqual(true);
});

how to run multiple functions respectively while using promises?

I'm trying to run 4 functions in order one by one, I've tried the code below, but some how the function stuck after running the first and the second ones
code exampl:
const Bluebird = require('bluebird');
///// also tried changing all Bluebird below to Promise -> didn't work
//const Promise = require('bluebird');
const promisesFunc = async (array) => {
let interval = 1000;
const delayPromise1 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise2 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise3 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise4 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
try {
/////////////// first attempt //////////////
await Bluebird.map(array, (data, index) => delayPromise1(data, index * interval))
await Bluebird.map(array, (data, index) => delayPromise2(data, index * interval))
await Bluebird.map(array, (data, index) => delayPromise3(data, index * interval))
await Bluebird.map(array, (data, index) => delayPromise4(data, index * interval))
console.log('done ***************************************************');
setTimeout(() => {
console.log('response was sent');
res.status(200).json('done')
}, 1000);
/////////////// second attempt ////////////
const promises = Bluebird.map(array, (data, index) => delayPromise1(data, index * interval))
.then(() => Bluebird.map(array, (data, index) => delayPromise2(data, index * interval)))
.then(() => Bluebird.map(array, (data, index) => delayPromise3(data, index * interval)))
.then(() => Bluebird.map(array, (data, index) => delayPromise4(data, index * interval)))
.then(() => {
setTimeout(() => {
console.log('response was sent');
res.status(200).json('done')
}, 1000);
})
.catch(err => console.error(err))
await Promise.all([promises]);
///////////// third attempt ////////////////////
const promises1 = array.map((data, index) => delayPromise1(data, index * interval));
const promises2 = array.map((data, index) => delayPromise2(data, index * interval));
const promises3 = array.map((data, index) => delayPromise3(data, index * interval));
const promises4 = array.map((data, index) => delayPromise4(data, index * interval));
await Promise.all([promises1, promises2, promises3, promises4]);
setTimeout(function(){
console.log('response was sent');
res.status(200).json('done')
}, 1000);
} catch (e) {
console.error(e);
}
}
promisesFunc(array)
Note in first and second attempt delayPromise1 and delayPromise2 functions runs successfully but then stops and doesn't continue, other solutions it doesn't work respectively
any idea why this is happening and is there any better solution to promisify these functions to run respectively.
PS functions structure is needed to be like this. and they need to run in order one after the other respectively.
mapping in an array of data , then do some work on it inside delayPromise functions, then resolve(). resolve the promise doesn't have to wait for the code execution to finish in some cases.
Your third attempt is the way to go. But you could send your response when your Promise.all resolve and all async operations are done.
const promises1 = array.map((data, index) => delayPromise1(data, index * interval));
const promises2 = array.map((data, index) => delayPromise2(data, index * interval));
const promises3 = array.map((data, index) => delayPromise3(data, index * interval));
const promises4 = array.map((data, index) => delayPromise4(data, index * interval));
await Promise.all([promises1, promises2, promises3, promises4]).then(() => {
console.log('response was sent');
return res.status(200).json('done')
})
If you want to run parallel pass all delay functions pass inside Promise.all. If you want to run sequentially use like below.
const promisesFunc = async (array) => {
let interval = 1000;
const delayPromise1 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise2 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise3 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
const delayPromise4 = (data, delayDuration) => {
return new Promise((resolve) => {
setTimeout(() => {
/// do some code here requires .map function may take 10s or more
resolve();
}, delayDuration)
});
};
try {
console.log("START");
await Promise.all(array.map((data, index) => delayPromise1(data, index * interval)));
console.log("Done delayPromise1");
await Promise.all((array.map((data, index) => delayPromise2(data, index * interval))));
console.log("Done delayPromise2");
await Promise.all(array.map((data, index) => delayPromise3(data, index * interval)));
console.log("Done delayPromise3");
await Promise.all(array.map((data, index) => delayPromise4(data, index * interval)));
console.log("Done delayPromise4");
console.log("DONE");
} catch (e) {
console.error(e);
}
};
promisesFunc([1, 2, 3])
I would use the array .reduce method like so:
[delayPromise1, delayPromise2, ...]
.reduce((m, delayPromise) => {
/* here we chain the promises */
return Promise.resolve(m).then(delayPromise)
}, {/* any input data to be the argument of delayPromise1 */} )
.then( res => {
// do something when all is ready
})

Completely lost with promise async/await

I'm trying to develop a relative simple test on NodeJS 11.6.x. I'm not really a developer, but sometimes try to do some coding.
My objective is to create a SQLite database and repeat some steps every time a run the code:
1. Drop a table if it exists
2. Create a table
3. Insert N lines
4. Count how many lines is in the database
5. Close the database
I tried first with a basic approach using callback, but couldn't figure out a way to make the step 3 (insert N lines) and looking for a solution, the promise async/await 'pattern' sounded the way to accomplish everything.
But, after refactoring the code, the step 1 (drop table) isn't running and I still not being able to execute step 3 (insert N lines) and have no idea what is happening. I also tried to use a promise package with no luck.
Could someone please have a look and help on this and if possible, explain and or give some advice?
Thanks in advance
Edited: Well, I'not used to post here at SO and don't know the 'right' way to update things here. I beleave I should had left the first code as reference, buy I don't have anymore.
Now I think I'm almoust there. All steps are executing in order. Just the step 3 (insert N lines) that I'm not able to make it work. Or it inserts and stops not going to the next '.then' or it just insert 1 line and I'm cannot visualize what is happening.
In the code, I commented in two lines with 'BUG 1:' and 'BUG 2:'.
If I both are commented, I get what is happening, it inserts only 1 line and don't continue the promise chain
If I comment BUG 1 and let BUG 2 active, it inserts just one line and continues. I think I understand why
If I comment BUG 2 and let BUG 1 active, it inserts all lines but don't continue and again, I think I understand why
If I uncomment both (the way I think should work. Don't work, and return an aditional error "Segmentation fault"
Bellow the code:
const sqlite3 = require('sqlite3')
let db = new sqlite3.Database('./test.db');
waitTime = 1
process.stdout.write('Starting...\n')
var test = new Promise((resolve, reject) => {
process.stdout.write('Drop Table... ');
db.run(`DROP TABLE IF EXISTS test`, (err) => {
if (err) {
process.stdout.write(`Dropping Error ${err.message}\n`)
reject()
} else {
setTimeout(() => {
process.stdout.write(`Dropped!\n`)
resolve()
}, waitTime)
}
})
})
test.then(() => {
return new Promise((resolve, reject) => {
process.stdout.write('Create Table... ')
db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
if (err) {
process.stdout.write(`Creating Error ${err.message}\n`)
reject()
} else {
setTimeout(() => {
process.stdout.write(`Created!\n`)
resolve()
}, waitTime)
}
})
})
}).then(() => {
return new Promise((resolve, reject) => {
process.stdout.write('Insert Line... ')
lines = 10
let loop = (async () => {
for (let i = 0; i < lines; i++) {
await new Promise(resolve =>
db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
if (err) {
process.stdout.write(`Inserting Error ${err.message}\n`)
throw (err)
} else {
setTimeout(() => {
// process.stdout.write(`Line ${i} Inserted!\n`)
process.stdout.write(`, ${i+1}`)
resolve() // BUG 1: if this line is commented, comment it, it will insert only 1 line
}, waitTime)
}
})
)
}
})()
process.stdout.write(`, IDone\n`)
resolve() // BUG 2: If this line is commented, the promise chain stops here
})
}).then(() => {
return new Promise((resolve, reject) => {
process.stdout.write('Count Line(s)... ')
db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
if (err) {
process.stdout.write(`Count Error ${err.message}\n`)
reject()
} else {
setTimeout(() => {
process.stdout.write(` ${rows[0].totalLines} Count!\n`)
resolve()
}, waitTime)
}
})
})
}).then(() => {
return new Promise((resolve, reject) => {
process.stdout.write('Select Line(s)... ')
db.all('SELECT data FROM test', [], (err, rows) => {
if (err) {
process.stdout.write(`Select Error ${err.message}\n`)
reject()
} else {
rows.forEach((row) => {
console.log(row.data);
})
setTimeout(() => {
process.stdout.write(`${rows[0].totalLines} Select!\n`)
resolve()
}, waitTime)
}
})
})
}).then(() => {
return new Promise((resolve, reject) => {
process.stdout.write('Close DB... ')
db.close((err) => {
if (err) {
process.stdout.write(`Closing Error ${err.message}\n`)
reject()
} else {
setTimeout(() => {
process.stdout.write(`Closed!\n`)
resolve()
}, waitTime)
}
})
})
}).then(() => {
console.log('Finished')
})
After the great explanation from #CertainPerformance (Thanks a lot), I was able to get it running. I believe it is now "the right" way to do it. May be there are some better ways, but for now, it is ok for me, bellow the final code:
const sqlite3 = require('sqlite3')
let db = new sqlite3.Database('./test.db');
lines = 10
process.stdout.write('Starting... ')
var test = new Promise((resolve, reject) => { process.stdout.write(`Promise Created...!\n`)
resolve()
})
test.then(() => { process.stdout.write('Drop Table... ')
return new Promise((resolve, reject) => {
db.run(`DROP TABLE IF EXISTS test`, (err) => {
if (err) {
reject(err)
} else { process.stdout.write(`Dropped!\n`)
resolve() }
})
})
}).then(() => { process.stdout.write('Create Table... ')
return new Promise((resolve, reject) => {
db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
if (err) {
reject(err)
} else {
process.stdout.write(`Created!\n`)
resolve() }
})
})
}).then(() => { process.stdout.write('Insert Line... ')
let insertLoop = (async () => {
for (let i = 0; i < lines; i++) {
await new Promise(resolve =>
db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
if (err) {
reject(err)
} else { ( i == 0 ) ? process.stdout.write(`${i + 1}`) : process.stdout.write(`, ${i + 1}`)
resolve() }
})
)
}
process.stdout.write(`, Inserted!\n`)
})()
return insertLoop
}).then(() => { process.stdout.write('Count Line(s)... ')
return new Promise((resolve, reject) => {
db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
if (err) {
reject(err)
} else { process.stdout.write(` ${rows[0].totalLines} Counted!\n`)
resolve()
}
})
})
}).then(() => { process.stdout.write('Close DB... ')
return new Promise((resolve, reject) => {
db.close((err) => {
if (err) {
reject(err)
} else { process.stdout.write(`Closed!\n`)
resolve()
}
})
})
}).then(() => {
console.log('Finished')
}).catch((err) => {
process.stdout.write(`The process did not finish successfully: ${err}`)
})
There are two main issues. First, in the second .then, you declare loop as an async function that is immediately invoked: this means that loop will resolve to a Promise. The trimmed code looks like:
}).then(() => {
return new Promise((resolve, reject) => {
let loop = (async () => {
// do some asynchronus stuff
})()
resolve() // BUG 2
})
}).then(() => {
Declaring a Promise alone will not cause the current thread to wait for it. The above code doesn't work as expected for the same reason that this code prints after immediately:
console.log('start');
const prom = new Promise((resolve) => {
setTimeout(resolve, 500);
});
console.log('after');
You must call .then on a Promise (or await the Promise) in order to schedule additional operations after the Promise completes. Or, if you're currently inside a .then, you can return the Promise, which will mean that the next .then will run as soon as the returned Promise resolves:
}).then(() => {
let loop = (async () => {
// do some asynchronus stuff
})();
return loop;
}).then(() => {
// this block will run once `loop` resolves
Note the lack of a new Promise((resolve... constructor above - inside a .then, just returning the next Promise is often the preferred way to go, since it means a lot less code and avoids an antipattern.
The other issue with the current code is that errors will not be caught. For example, if your
db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
if (err) {
process.stdout.write(`Inserting Error ${err.message}\n`)
throw (err)
// else call resolve()
throws an error, the Promise that's currently being awaited at that point will never resolve, nor will it reject - it will remain pending and unfulfilled forever. You should pass reject as the second argument to the Promise constructor, and call it when there's an error (instead of throw), for example:
await new Promise((resolve, reject) => {
db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
if (err) {
process.stdout.write(`Inserting Error ${err.message}\n`)
reject(err)
} else {
// ...
This way, the awaited Promise will get rejected, which means that the whole loop will reject, and if the loop is returned, it'll allow a .catch to catch the error, for example:
var test = new Promise((resolve, reject) => {
// ...
});
test.then(() => {
return new Promise(...
// ...
})
.then(() => {
return new Promise(...
// ..
})
.then(() => {
return new Promise(...
// ..
})
.catch((err) => {
process.stdout.write(`The process did not finish successfully:`, err)
// handle errors
});
Note that, unless each db. function call needs to execute serially, it would be better to make all the requests at once, and resolve once each request has finished - this can significantly reduce the time required for the script to run. Create an array of Promises for each asynchronous call, then call Promise.all on that array to get a Promise that resolves when all of those Promises are done (or, rejects as soon as one of those Promises rejects). For example, for the second .then:
}).then(() => {
process.stdout.write('Insert Line... ')
const proms = Array.from(
{ length: lines },
(_, i) => new Promise((resolve, reject) => {
db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
if (err) {
process.stdout.write(`Inserting Error ${err.message}\n`)
reject(err)
} else {
setTimeout(() => {
// process.stdout.write(`Line ${i} Inserted!\n`)
process.stdout.write(`, ${i+1}`)
resolve()
}, waitTime);
}
});
})
);
return Promise.all(proms);
}).then(() => {
Nothing else in your code looks to deal with asynchronous loops, luckily.
You may also consider a utility function like Promisify which will turn callback-based functions to Promises without all the extra new Promise(... boilerplate every time there's an asynchronous call.
Further improvements can be made by promisifying db into reusable functions, and leveraging the full power of async/await instead of mixing it with then:
const sqlite3 = require('sqlite3')
let db = new sqlite3.Database('./test.db');
function runDbAsync(sql) {
return new Promise((resolve, reject) => {
db.run(sql, (err) => {
if (err) reject(err);
else resolve();
});
});
}
function getDbAsync(sql, val) {
return new Promise((resolve, reject) => {
db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
if (err) reject(err);
else resolve(rows);
});
});
}
function closeDbAsync() {
return new Promise((resolve, reject) => {
db.close((err) => {
if (err) reject(err);
else resolve();
});
});
}
function write(text) {
process.stdout.write(text);
}
function writeLn(text) {
write(text + "\n");
}
async function main() {
const lines = 10
writeLn('Starting... ')
write('Drop Table... ');
await runDbAsync(`DROP TABLE IF EXISTS test`);
writeLn(`Dropped!`);
write('Create Table... ');
await runDbAsync(`CREATE TABLE IF NOT EXISTS test (data TEXT)`);
writeLn(`Created!`);
write('Insert Line... ');
for (let i = 0; i < lines; i++) {
await runDbAsync(`INSERT INTO test (data) VALUES ('a')`);
write( i == 0 `${i + 1}` : `, ${i + 1}`);
}
writeLn(`, Inserted!`);
write('Count Line(s)... ')
const rows = getDbAsync(`SELECT COUNT(*) AS totalLines FROM test`, []);
writeLn(` ${rows[0].totalLines} Counted!`)
write('Close DB... ');
await closeDbAsync();
writeLn(`Closed!`);
}
main().then(() => {
console.log('Finished')
}, err => {
writeLn(`The process did not finish successfully: ${err}`)
});

Bluebird Promises with Event Emitter

I am fairly new with using Bluebird promises. I was trying to use them over an emitter. However, I am stuck on how to handle errors.
I have a stream object which is the emitter. Code is as below -
return new Promise((resolve, reject) => {
var onDocFunc = doc => {
//JSON.parse('*');
// some logic goes in here to construct setStmt
bulk.find(query).upsert().update({$set: setStmt});
count++;
if (count % bulkSize == 0) {
stream.pause();
var execute = Promise.promisify(bulk.execute);
execute().catch(() => {}).then(() => {
stream.resume();
});
}
};
stream.on('data', onDocFunc);
stream.on('end', () => {
JSON.parse('*'); // how to catch errors that happen here??
var boundResolve = resolve.bind(this, {count: count});
if (count % bulkSize != 0) {
Promise.promisify(bulk.execute)().then(boundResolve).catch(boundResolve);
}
else {
boundResolve();
}
});
stream.on('error', err => {
reject(err);
});
})
I want to know what is the recommended way to catch an error which occurs inside the callback of the end event handler? Right now if any error occurs, the NodeJS application crashes with uncaughtException: Unexpected token *
Don't mix application logic into the promisification of the event emitter. Such code (that can throw etc) should always go in then callbacks. In your case:
var execute = Promise.promisify(bulk.execute);
return new Promise((resolve, reject) => {
stream.on('data', onDocFunc); // not sure what this does
stream.on('end', resolve);
stream.on('error', reject);
}).then(() => {
JSON.parse('*'); // exceptions that happen here are caught implicitly!
var result = {count: count};
if (count % bulkSize != 0) {
return execute().catch(()=>{}).return(result);
} else {
return result;
}
});
Regarding your real code, I'd probably try to factor out the batching into a helper function:
function asyncBatch(stream, size, callback) {
var batch = [], count = 0;
stream.on('data', data => {
batch.push(data);
count++;
if (batch.length == size) {
stream.pause();
Promise.resolve(batch).then(callback).then(() => {
batch = [];
stream.resume();
}, e => {
stream.emit('error', e);
});
}
});
return new Promise((resolve, reject) => {
stream.on('end', resolve);
stream.on('error', reject);
}).then(() => batch.length ? callback(batch) : null).then(() => count);
}
Promise.promisifyAll(Bulk);
return asyncBatch(stream, bulkSize, docs => {
const bulk = new Bulk()
for (const doc of docs) {
// JSON.parse('*');
// some logic goes in here to construct setStmt
bulk.find(query).upsert().update({$set: setStmt});
}
return bulk.executeAsync().catch(err => {/* ignore */});
})
You'll have to use a try/catch block:
stream.on('end', () => {
try {
JSON.parse('*')
// ...the rest of your code
} catch (e) {
reject(e)
}
})

promise chaining when splitting the chain

In the following code
var p = new Promise((resolve, reject) => {
console.log('a');
resolve();
});
p.then(() => {
console.log('b');
}).then(() => {
console.log('c');
});
p.then(() => {
console.log('z');
})
I expect the console output to be:
a
b
c
z
Instead I got:
a
b
z
c
but with this code I got the expected result
var p = new Promise((resolve, reject) => {
console.log('a');
resolve();
}).then(() => {
console.log('b');
}).then(() => {
console.log('c');
});
p.then(() => {
console.log('z');
})
Can anyone explain the way promise chaining is done in this case?
Each then returns you new Promise which depends of callback resolution.
That's difference.
var p = new Promise((resolve, reject) => {
console.log('a');
resolve();
});
var a = p.then(() => {
console.log('b');
});
a.then(() => {
console.log('c');
});
p.then(() => {
console.log('z');
});
Timeline:
initial resolve // a
p resolved // b, z independently
a resolved // c
In second case your p points to promise returned by last then:
var a = new Promise(foo('a'));
var b = a.then(foo('b'));
var p = b.then(foo('c'));
p.then(foo('z'));
You should not to rely on one level resolving order. Because this happens eventually and order is realy undefined(depend on internal implementation).

Resources