I have existing code that does the following use of hrtime
before = process.hrtime()
// stuff happens...
after = process.hrtime(before)
latency = (after[0] * 1000000000 + after[1]) / 1000000;
What unit is latency above?
Turns out the above is in fact milliseconds. Since setTimeout takes the delay value in milliseconds, it's easy to validate my hrtime juggling:
const times = []
const delays = [1, 10, 100, 1000, 1001, 1100];
function sleep(ms) {
return new Promise((res) => {
setTimeout(res, ms);
});
}
async function main() {
for (let ms of delays) {
const ping = process.hrtime();
await sleep(ms);
const pong = process.hrtime(ping);
const latency = (pong[0] * 1000000000 + pong[1]) / 1000000;
times.push(latency);
}
console.log(times);
// >>> [2.031091, 11.623596, 101.971041, 1000.554953, 1001.192077, 1104.29338]
}
main();
Related
I want to run a Script every 6 Hours
const { IgApiClient } = require("instagram-private-api")
const ig = new IgApiClient()
const USERNAME = "abc"
const PASSWORD = "xyz"
ig.state.generateDevice(USERNAME)
const main = async () => {
var birthday = new Date(2069, 05, 14);
var today = new Date();
birthday.setFullYear(today.getFullYear());
if (today > birthday) {
birthday.setFullYear(today.getFullYear() + 1);
}
var daystill = Math.floor((birthday - today) / (1000*60*60*24))
await ig.simulate.preLoginFlow()
await ig.account.login(USERNAME, PASSWORD)
process.nextTick(async () => await ig.simulate.postLoginFlow())
await ig.account.setBiography(`${daystill} Days till my Birthday, Today is ${new Date().getDate()}/${new Date().getMonth()}/${new Date().getFullYear()}. (AutoGenerated)`)
}
main()
instagram-private-api
About Script: update my Instagram Bio with Async Await
Problem / Goal:
I Tried using node-cron, but It returns some Error (I think Async is causing the Problem), I also tried while loops and setInterval()s
I want this Script/File to run every 6 Hours, I have a heroku account (if that helps)
Error when i use node-cron:
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
Code for node-cron:
cron.schedule('* * * * *', () => { // this is not every 6hrs
const main = async () => {
//same as above
}
main()
})
Doing it the async await way as the title says.
// used to measure time
import { performance } from 'perf_hooks';
const interval = 1000; // in ms
(async function main(){
let start_time = performance.now();
// do stuff
let stop_time = performance.now();
let timeout = interval - (stop_time - start_time);
setTimeout(main, timeout);
})();
edit:
To explain the syntax behind the main function.
()(); will automatically call the function inside of first braces on script start.
I need to ratelimit my requests to moralis speedy nodes (1500 req/min), I tried to make a counter with dates to limit it at 1450 but because my requests are async it does not work at all. Any suggestions?
here is my implementation if anyone is interested
let rate = 0
const rateLimit = () => {
if (rate < 1450) {
if ((rate = 0)) {
time = Date.now();
}
rate = rate + 1;
return true;
} else {
if (Date.now() - time > 6000) {
rate = 0;
}
console.log("Rate limit reached");
return false;
}
};
I'm attempting to clean up my code with Promises and Async await. My problem is that I need these requests to be recallable with the same handling afterwards.
I've tried Promises, but if I nest everything in functions, it gets really messy fast. How do I make this code so that it only continues in the go() async function when a value is returned?
const request = require('request-promise');
require('console-stamp')(console, 'HH:MM:ss.l');
const colors = require('colors');
const kws = 'sweatsasaaser'.toLowerCase();
const size = 'Small';
go();
async function go(){
const f = await getproduct()
console.log('Finished ' + f)
if (f == undefined) getproduct()
}
async function getproduct(){
console.log('Requesting')
let result = await request('https://www.supremenewyork.com/mobile_stock.json');
let data = JSON.parse(result);
let prodid;
for (var i = 0; i < data.products_and_categories['Tops/Sweaters'].length; i++){
if (data.products_and_categories['Tops/Sweaters'][i].name.toLowerCase().includes(kws)){
console.info('Found product: '.green + data.products_and_categories['Tops/Sweaters'][i].name.green);
return prodid = data.products_and_categories['Tops/Sweaters'][i].id;
};
};
if (prodid == undefined){
console.log(`Product id: ${prodid}`.blue);
return prodid;
}
else {
setTimeout(function(){
//getproduct()
}, 4000);
}
}
Write a separate function:
/**
* Re-executes an async function n times or until it resolves
* #param {function} fn Function to call
* #param {number} [times=3] Times to retry before rejecting
* #param {number} [delay=1000] Delay between retries
* #param {number} [i=0] Counter for how many times it's already retried
*/
async function retry(fn, times = 3, delay = 1000, i = 0) {
try {
return await fn()
} catch (error) {
if (i < times) {
await new Promise(r => setTimeout(r, delay))
return retry(fn, times, delay, i + 1)
}
else throw error;
}
}
Have your main function getproduct simply throw the error
else {
// setTimeout(function(){
// //getproduct()
// }, 4000)
throw new Error('Cannot get productid')
}
And use it with the new retry function:
async function go(){
const f = await retry(getproduct, 3)
In case you wanna pass arguments, simply wrap it
const f = await retry(() => getproduct(...args), 3)
the code i am running when using promise.all should run at about \8 the time when i am using regular "blocking" for, but the result is very similar not even half the time.
i have tried to run this 2 NODEJS programs in the same computer.
WHEN USING PROMISE.ALL
let user = { "name": "shay", "interests": ["category1", "category2", "category3", "category4", "category5", "category6", "category7", "category8", "category9", "category10"] }
let result = [];
let Companies = [];
for (i = 0; i < 3000000; i++) {
let company = { "name": "company" + i, "interest": "category" + (Math.floor(Math.random() * 10) + 1) };
Companies.push(company);
}
const successRate = () => {
return (Math.floor(Math.random() * 100) + 1) + "%"
}
const task = function (interest) {
return new Promise((resolve, reject) => {
Companies.forEach(company => {
if (company.interest == interest)
result.push({ "company": company.name, "interest": company.interest, "success": successRate() })
});
resolve('succeed!');
});
};
const run = async function () {
let tasks = user.interests.map(interest => {
return task(interest)
});
await Promise.all(tasks);
}
const start = Date.now();
run();
WHEN USING REGULAR FOR
let user = {"name":"shay","interests":["category1","category2","category3","category4","category5","category6","category7","category8","category9","category10"]}
let result =[];
let Companies = [];
for (i=0;i<3000000;i++)
{
let company = {"name":"company"+i,"interest":"category"+(Math.floor(Math.random() * 10) + 1)};
Companies.push(company);
}
const successRate=()=>{
return (Math.floor(Math.random() * 100) + 1)+"%"
}
const start = Date.now();
user.interests.forEach(interest => {
Companies.forEach(company => {
if (company.interest==interest)
result.push({"company":company.name,"interest":company.interest,"success":successRate()})
});
});
console.log("run time",Date.now()-start);
the promise.all total run time is 1314
the regular for total run time is 1430
Node.js follows a single threaded architecture, it doesn't create a new thread for a new promise - everything runs in the same thread. Asynchronous behaviour is achieved via event loop, underlying OS concurrency and libuv. If you're familiar with Nginx - it actually works pretty much the same way. So don't mix JavaScript's Promise<> with Java's Future<>.
I am triing to get execution time of async function. Seemingly I can use process.hrtime for this. I created simple example:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime();
console.log("end");
console.log(end);
}, 1000);
It outputs
starting
start
[ 131806, 731009597 ]
HELLO
end
[ 131807, 738212296 ]
But I don't understand where is exectuion time in miliseconds? I expect to get 1000 ms in this example.
Got it:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime(start);
console.log("end");
console.log(end);
}, 1000);
Prints
starting
start
[ 132798, 207101051 ]
HELLO
end
[ 1, 7001730 ]
That means 1 second and 7001730 nanoseconds from start to end
Since Node 10.7.0, process.hrtime is marked as 'legacy', with the recommended method being process.hrtime.bigint. The documentation contains an example of how to use this method to time an operation:
const start = process.hrtime.bigint();
// 191051479007711n
setTimeout(() => {
const end = process.hrtime.bigint();
// 191052633396993n
console.log(`Benchmark took ${end - start} nanoseconds`);
// Benchmark took 1154389282 nanoseconds
}, 1000);
Just to add in case someone needs the execution time in ms:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime(start); // end[0] is in seconds, end[1] is in nanoseconds
const timeInMs = (end[0]* 1000000000 + end[1]) / 1000000; // convert first to ns then to ms
console.log("timeInMs:", timeInMs);
}, 1000);
Here's a simple wrapper timing function for async functions:
// async function execution time wrapper
async function fnTime(fn, ...params) {
const start = process.hrtime()
const result = await fn(...params)
const end = process.hrtime(start)
console.log(
`[${fn.name}] Execution time:${(end[0] * 1000000000 + end[1]) /
1000000} ms`
)
return result
}
example usage (see this demo on repl.it):
// usage
const setTimeoutPromise = ms => new Promise(resolve => setTimeout(resolve, ms))
// example 2:
// get name from db
const db = {
async getUser(id){
// simulate wait for record retrival from db
await fnTime(setTimeoutPromise, 150)
return {
_id: id,
name: 'John Doe',
organisation: 'UN',
email: 'johndoe#un.org'
}
}
}
// test it
;(async function(){
const result = await fnTime(db.getUser, 'asfa98th4nfwef0qwrwef0')
console.log('result', result)
})()
// result:
// [setTimeoutPromise] Execution time:197.928094 ms
// [getUser] Execution time:199.480553 ms