jsdelivr / globalping

A global network of probes to run network tests like ping, traceroute and DNS resolve
https://globalping.io
270 stars 33 forks source link

Credits support #478

Closed MartinKolarik closed 9 months ago

MartinKolarik commented 10 months ago

Following #473, we need to allow the users to spend the credits they have. The logic is similar to the existing rate limits, with 1 test location = 1 credit. The credits are used only if the user's hourly quota is not sufficient to fulfill the request.

Example: The user requests a measurement with 5 locations and has 2 more requests in their hourly quota. His remaining hourly quota is set to 0, and 3 credits are spent from their account. If they don't have enough credits, nothing happens, and the request is rejected.

There is a question of how we represent the credit spending in the DB. Right now, we have a separate entry for each addition, which is good for record keeping but hard to actually use here. I'm thinking we:

To maintain consistency, we can then set triggers on the additions/deduction tables so that the apps work with the DB in the following way (I can do the SQL part if needed):

Both operations are then one simple query from the app's perspective (and one hidden query in the DB, which is still lightweight).

When credits are involved in handling the request, it would be good to also add two new headers: X-Credits-Remaining and X-Credits-Cost

alexey-yarmosh commented 9 months ago

Insert to credits_additions may happen even when associated users are not registered. Since they don't have userId it is not possible create a row in credits for them. That means users can't get credits for their donations/adoptions before they are registered on dashboard.

I can add a e.g. consumed: false column to credits_additions and set it to true only if value was added to credits. Then, on user sign up it is possible to go through all additions and give them all their prev credits.

MartinKolarik commented 9 months ago

That seems nice, sure. So when you start sponsoring and register only sometime later, you'll get all the credits.

alexey-yarmosh commented 9 months ago

Should X-RateLimit-Limit return values as previously? Or include available credits data?

MartinKolarik commented 9 months ago

Existing headers as before and this:

When credits are involved in handling the request, it would be good to also add two new headers: X-Credits-Remaining and X-Credits-Cost

alexey-yarmosh commented 9 months ago

Oh, missed that description part.

MartinKolarik commented 9 months ago

Should be possible with our DB too now: https://mariadb.com/kb/en/insertreturning/

Maybe will need a raw query if knex doesn't know it yet.

alexey-yarmosh commented 9 months ago

We need to update gp_credits instead of inserting. Since there is no UPDATE...RETURNING it still looks doable with INSERT INTO ... ON DUPLICATE KEY UPDATE ... RETURNING, where insert does nothing (amount: 0) and subtraction logic is inside ON DUPLICATE KEY UPDATE.