web3js RateLimiting my requests to the node - node.js

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;
}
};

Related

Exponential memory growth Node.js, memory leak?

I'm making a script to fetch blockchain transactions, however the memory usage by the process grows untill it uses around 4 gigabytes and crashes. I suspect it is a memory leak and has something to do with the garbage collection mechanism.
async function getTransactions(blockNumber) {
if (blockNumber < 15000000) {
let block = await web3.eth.getBlock(blockNumber);
for (let i = 0; i < block.transactions.length; i++) {
let transaction = await web3.eth.getTransactionReceipt(block.transactions[i]);
for (let j = 0; j < transaction.logs.length; j++) {
try {
if (transaction.logs[j].topics[0] == "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") {
let parsed1 = transaction.logs[j].topics[1].replace("0x", "").replace(/^0+/, '');
let parsed2 = transaction.logs[j].topics[2].replace("0x", "").replace(/^0+/, '');;
let contract = new web3.eth.Contract(erc20_abi, transaction.logs[j].address)
let decimals = await contract.methods.decimals().call();
let transfer = {
from: "0x" + parsed1,
to: "0x" + parsed2,
token: transaction.logs[j].address,
amount: parseInt(transaction.logs[j].data) / (10**decimals),
block: block.number,
timestamp: block.timestamp,
hash: transaction.logs[j].transactionHash,
}
console.log(transfer);
await createTransfer(transfer)
}
} catch (error) {
}
}
}
}
}
(async () => {
await connectdb();
for (let i = await findMax(); i < 15000000; i++) {
await getTransactions(i);
}})();

Function that gets past messages stopped working. Any way to fix?

I got this function from another stackoverflow question. I fixed it to work with Discord.js v12 by changing channel.fetchMessages to channel.messages.fetch. The function worked at first and everything was fine, but then one time when I started up my program it started showing this error: "TypeError: Cannot read property 'id' of undefined" This error occurs at line 55 which is last_id = messages.last().id; I did not change the function at all and it just stopped working. Any ideas?
async function lots_of_messages_getter(channel, limit = 6000) {
const sum_messages = [];
let last_id;
while (true) {
const options = { limit: 100 };
if (last_id) {
options.before = last_id;
}
const messages = await channel.messages.fetch(options);
sum_messages.push(...messages.array());
last_id = messages.last().id;
if (messages.size != 100 || sum_messages >= limit) {
break;
}
}
return sum_messages;
}
becuase sum_messages will never be greater or same as limit because it's not a number, it must be sum_messages.length and a check after getting the messages if(messages.size === 0) would also not hurt
async function lots_of_messages_getter(channel, limit = 6000) {
const sum_messages = [];
let last_id;
while (true) {
const options = { limit: 100 };
if (last_id) {
options.before = last_id;
}
const messages = await channel.messages.fetch(options);
if (messages.size === 0) {
break;
}
sum_messages.push(...messages.array());
last_id = messages.last().id;
if (messages.size != 100 || sum_messages.length >= limit) {
break;
}
}
return sum_messages;
}

Converting process.hrtime() to milliseconds

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();

function in setInterval waits till other process function ends node

My app makes some work then makes query to db. It is reaping every 3 seconds, the app must have only 1 active connection to db, if connection is active must wait then do it, I have tried this:
var state = false;
let l = 0;
function sleep(ms) {
console.log('object');
l++;
return new Promise(resolve => setTimeout(resolve, ms));
}
async function lol(orderid) {
if (state == true) {
await sleep(1000 + l * 1000);
let k = await lol(orderid);
return k;
};
state = true;
let res = await getOrders(`(${orderid})`, 1500, 20)
state = false;
return res;
}
let orderid = 14136377;
setInterval(async () => {
let m = await lol(orderid++);
console.log(m[0]['json_build_object']['order']['orderid']);
}, 1000);
Now it's making query for sorted ID witch every time incremented and output it.This is results
condition if (state == true || l >0 ) don't give response,all interval calls stays alive.
As you can see sometimes it's not consecutive. How to make it consecutive?
Are there any better ways to make this ?
If think this will be enough.
let state = false;
let data = [];
getorerids().then(res => {
if(state){
data.push(res);
}else {
state = true;
dbcall(res);
}
});
dbcall(ids)
.then(res =>{
dosmtwithids(res);
if(data[0]){
return dbcall(data.pop());
}else {
state = false;
}
});
dosmtwithids(){
.......
};
setInterval(getorerids, 3000);

Generating a steady volume of events and sending them to a UDP server

The following code generates a steady volume of MAX events and uses the sendEvent() function to send a document to a UDP server.
Currently, for some reason, the ack rate (last parameter in the single console.log call) starts at 100% and gradually reduces to about ~50%, then there's a hiccup and it goes back to 100%, then back to ~50% over and over again. I'm wondering why this happens, why doesn't it stay on 100% or at least close to it? Why does it reduce to around 50% and then goes back to 100%? My goal is to keep it as close as possible to 100% at all times.
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
var HOST = '127.0.0.1';
var PORT = 3333;
var MAX = 100;
var counter = 0;
var start = new Date().getTime();
var eps = 0;
var sent = 0;
var ack=0;
function sendEvent() {
var doc = {
timestamp: new Date().getTime()
};
var message = new Buffer(JSON.stringify(doc));
sent++;
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
ack++;
});
}
function run() {
counter++;
var current = new Date().getTime();
var lapsed = current - start;
var lapsedSec = lapsed / 1000;
eps = sent / lapsedSec;
if (eps < (MAX === 0 ? eps + 1 : MAX))
sendEvent();
if (counter % 100000 === 0) {
counter = 0;
console.log('eps', eps, counter, sent, (ack/sent*100).toFixed(2));
}
if (counter % 1000 === 0) {
setInterval(run, 1);
}
else
run();
}
run();

Resources