Limiting Axios outgoing requests to an external API (Rate Limiting) - node.js

I am working with several APIs on my app and a few of them have limits that are not just simply per sec.
For example one of my apis has the following limits:
Max 100 requests per 2 minutes
Max 20 requests per 1 second
So I have tried implementing this library https://github.com/aishek/axios-rate-limit in the following way:
axiosRateLimit(baseAxios.create(), {
maxRequests: 1, // 1
perMilliseconds: 1200 // per 1.2 seconds
// 100 requests per 2 minutes, 50 requests per 60 seconds, 60 seconds / 50 requests = 1 per 1.2 seconds
});
But it can't take advantage of the 20 requests per 1 second limit, because to adhere to the 100 requests per 2 minutes, I have to limit it to 1 per 1.2 seconds, otherwise if I limit it to 20 per second, I can do 2400 requests in 2 minutes.
So how can I implement both conditions and have them both working together?
What if I need to do only 50 requests every 2 minutes, with the current implementation, it will take me 1 minute for all of them, and I am not taking advantage of the 20 per second (becaus if I do, I can do it in 3 seconds, instead of 1 minute).
Is there a way to accomplish this with this library? Initially I thought that the maxRequests works with perMilliseconds and maxRPS can be used to handle the other case, so when all 3 are supplied I thought it would be like:
{
maxRequests: 100, // 100 max requests
perMilliseconds: 2 * 60 * 1000, // per 2 minutes
maxRPS: 20 // 20 max per second
}
But the docs say:
// sets max 2 requests per 1 second, other will be delayed
// note maxRPS is a shorthand for perMilliseconds: 1000, and it takes precedence
// if specified both with maxRequests and perMilliseconds
const http = rateLimit(axios.create(), { maxRequests: 2, perMilliseconds: 1000, maxRPS: 2 })
So obviously it doesnt work the way I expected it to work, is there a way to achieve what I want?
Are there any other libraries that can do what I want?
Do I have to implement it from scratch on my own?

Related

Sequential ledger-like entries in NodeJS with Async/ Await

I'm designing an accounting/ book-keeping application and my table has the following columns -
Transaction ID
Transaction Details
Amount
Closing Balance
All the transactions are fed to NodeJS function one-by-one through a queue
However, while saving each transaction, I have to fetch the previous transaction to get the last closing balance and add current transaction amount to the same to get the new closing balance
But I have to use async/await to fetch previous transaction so the event loop is free for a few milliseconds during which the function receives a new transaction event from the user. This is causing a lot of inconsistencies with the data as sometimes 2 rows with the same closing balance are inserted.
const prevTransaction = await Transaction.findOne({
where: { userId },
order: [['createdAt', 'DESC']]
})
await Transaction.create({
userId,
amount,
closingBalance: prevTransaction ? prevTransaction.closingBalance + amount : amount,
transactionDate
})
Now if the system receives a lot of events in bulk then there could be some inconsistencies in data due to the gap between GET & INSERT query.
In some scenarios, this is the data that's inserted
ID
Amount
ClosingBalance
1
20
20
2
20
40
3
20
40
4
10
50
5
20
60
When ideally it should be -
ID
Amount
ClosingBalance
1
20
20
2
20
40
3
20
60
4
10
70
5
20
90
Any particular way I could tweak the above code to get the sequential effect?
This is the reason I'm using a BullJS queue is so that transactions are processed one-by-one. But this issue still persists because of the 2 await calls.
I have temporarily solved this problem by pausing the job queue if any transaction is being processed and resuming it once the transaction is inserted - link
Would love to hear about any alternate approaches since this approach is relying on a third-party library.

How to display 1 hour 46 minutes in MS Excel cell where both the number count of hours and minutes comes from calculation?

Suppose I sleep for 7 hours and 36 minutes. I have a sleeping threshold of 5 hours and 54 minutes. If I sleep more than threshold time, I get the time difference and If i sleep less than or equal to my sleeping threshold, i get the output as 'You slept Good". To do so, I scaled zero to 60 minutes of actual time to 0 to 1 on a decimal scale, this way 7 hours 36 minutes comes as 7.6 and 5 hours 54 minutes comes as 5.9.
Now, I take their difference which comes out to be 1.7 i.e. I slept extra for 1 hour and 0.7 minutes on 0to1 scale (which equals 1 hour 42 minutes on actual time scale).
So, I used TRUNC function to display 1 h (i.e ! hour); however I can't get my mind working as to how I can display 42 minutes in the same cell.
i.e. my output should be 1h 42 min
This should work:
=IF(B2+C2/60>5.9,LEFT(B2+C2/60-5.9)& "hr "&ROUND(((B2+C2/60-5.9)-VALUE(LEFT(B2+C2/60-5.9)))*60,0)&"min","You slept good")
However, you wouldn't be able to do further calculations, as it is a text.
Also assumes you will not oversleep by more than 10 hrs :)

How to calculate Pacing time in load runner

I have to run 100 iterations with 50 users. The total duration of the test is 1 hour. 1 user can do 2 iterations and the number of transactions in the script is 6.
How to calculate pacing time?
Example:
1000 Users, 10000 Full Iterations per hour
10,000/1,000 = 10 iterations per user per hour
3600 seconds per hour /10 iterations per user per hour = one iteration every 360 seconds ( six minutes ) on average
The random algorithm in LoadRunner is based upon the C rand() function, which is approximately (but not exactly ) uniform for large datasets. So, I take the average pacing interval from the start of one iteration to the next and then adjust it by plus/minus 20%.
So, your 360 ( 0:06:00 ) second pacing becomes a range from 288 seconds (0:04:48) to 432 seconds (0:07:12 ).
You would run these calculations for each business process you want to stage
For think time look to your production logs for information on the range of users from page X to Page X+1. This is easily achievable since each top level page refers to the REFERER, or previous page that it came from. A comparison of the timestamps grouped by client IP can provide that range you need for think times.
Always Apply Little's Law for calculate Pacing, ThinkTime, No.of VUsers
From Little's Law: No of VUsers= Throughput*(Responce_Time + Think_Time)
Expl.
Throughput= Total No of Transactions/Time in Seconds
, Pacing= (Response_Time + Think_Time)
From Your Requirements-
Total No of iterations 100 and 1 iteration have 6 transactions, So total no of transactions = 600
Throughput for 1 Minute is: 600/60 = 10
, Throughput for 1 Sec is: 0.16
According to formula 50 = 0.16*(Pacing)
Pacing = 312.5 seconds
To achieve 100 Iterations in 1 Hour you have to set pacing 312.5 seconds, Make sure Pacing = Response_time + Think_Time.
Pacing is the 'inter-iteration' gap and it is used to control the rate of iterations during the test. If the goal for 1 user is to complete 2 iterations per hour, that results into a Pacing of 1800sec (little's law mentioned above) . Now as long as the summation of resp times of those 6 transactions and think time between them is less than 1800s, you will be able to achieve the desired rate.
NOTE: iteration is not equal to transaction, unless the iteration has just one transaction. Refer this to get a pictorial understanding
https://theperformanceengineer.com/2013/09/11/loadrunner-how-to-calculate-transaction-per-second-tps/
Pacing is the wait time between iterations so i'm agree with #CyberNinja, in your use case pacing is 1800s because it's the max duration of your script that achieve your goal : produce 100 iterations with 50 users in a hour.
Pacing is not Response_time + Think_Time!
According to Little's Law :
No. of Concurrent Users(N) =
Throughput or TPS(X) * [
Response Time (RT) + Think Time (TT) + Pacing (P)
]
Here RT+TT is Script Execution Time SET which you can calculate by running script once and adding up all the RT of transactions and all think times.
Assume SET to be 60 seconds.
As per your question
total transactions in 1 hr =
100(Iterations) *
50(Users) *
2(Each User Iteration) *
6(No. of Transactions)
= 60000 Transactions/hr
Converting it to TPS = 60000/3600 = 16.66
Now Putting all values in Little's Law:
50 = 16.66 (60 - Pacing)
Pacing = 60 - 50/16.66
Pacing = 57 secs (approx).

SharePoint. How to run timerjob every 90 minutes

I have a web.config setting like IntervalInMinutes. I would like to use the setting value to create my SPSchedule instance and run my job. The interval should be set in minutes.
I know how to use SPMinuteSchedule and run the job every 0 < n < 60 minute or how to use SPHourSchedule and run the job every 0 < n < 24 hours, But what if I want to have 90 or 2000 minutes interval as the setting value?
So, the question is: what should I do to run the job with the minutes interval 0 < n < 100000?
Thank you.
It's not a very robust solution, but I think you'll have to use an appropriate number of the SPDailySchedule objects.
In case of the 90 minutes interval it is:
24 h / 1.5 h = 16

theoretical Question about multithreading (scaling)

I need to answer following question:
A server needs to do 15 ms of work per request for a file. if the file is not in cache, the harddisk must be accessed and thread sleeps for 75 ms. This happens in 1/3 of the cases.
a) How many request can the server process per second with 1 Thread?
->15 ms + 1/3 * 75 ms = 40 ms per request -> 1000/40 ms = 25 Request per second
b) How many with multiple threads?
Is there a formula for this?
For 2 threads I got 40.625 Request per second:
25 ms pause on average -> 25/40 = 0.625 -> 25 * 1.625 = 40.625 Requests per second
What about 3 or more threads?
I know I'm doing your homework but it is interesting because the problem statement is flawed. It can't be answered as-is because a important piece of info is missing: the number of cores that the machine has available. Running more threads than you've got cores doesn't improve throughput. Assuming J jobs, T threads and C cores, the amount of time spent on them is
time = J x 15 msec / min(T, C) + J x 75 msec / 3
Solving for J per second:
rate = 1000 / (15 / min(T, C) + 25)

Resources