PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Monday, September 5, 2022

[FIXED] How do I track users in my database without affecting response times?

 September 05, 2022     design-patterns, fastapi, redis     No comments   

Issue

I'm designing a big (for me) backend API with users and I want to try when users were last seen, and what IPs they are seen with (all of them).

The usual way I do this is with a simple middleware - the middleware checks if they are authenticated. If they are, it simply updates a database entry with the current time. Then the middleware just continues to the requested function.

However, I'm dealing with more data and I want this to be done as smoothly as possible - I want the middleware to finish ASAP with no blocking database operations. I have some ideas:

  1. I use FastAPI's background tasks to do this. I don't know how much overhead they induce, and given that they would be ran on EVERY route, this seems inefficient to be creating a background task just to update a timestamp in a database. If I want this to scale, I'd have to use celery or something, which might be even slower.

  2. Redis. This seems most likely; I could simply store the timestamp and IP keyed by their address. On an interval (15-60s), I could have the API look at all the entries and update the database accordingly. This should make the requests as fast they could be, no overhead, very scalable, and the true disk database would be updated in a period that is roughly 'real time'. I like this solution, but I worry it may be classified as premature optimization.

To be clear, the requirements I'm looking for are

  • Scalable. This has to work when 10,000 users are hitting my API simultaneously, otherwise I have to drop the feature.

  • Responsive - The design is probably going to use a middleware of sorts, and this has to exit instantly. I cannot have a working waiting on something like a DB transaction to go through. The response time must not be hindered by this feature.

  • Relatively Real-time - The database has to have these IPs and User IDs usable in less than 60 seconds. I could get fleixble with this requirement, but I'd rather not be waiting too long before things can be queried.


Solution

My answer may not be the definitive answer, but here are my two cents:

PREMISE

  • 10k users are quite a lot, but it mostly depends on what you do with those 10k requests. Your app, with or without this feature, may not be capable of handling such traffic. Hence it should be horizontally scalable
  • You'll need to accept some sort of trade-off between features and scalability. The beauty of horizontal scalability, is that if you need more resources, you just add horizontally a server/service.
  • It's difficoult that have near real-time if you're doing some heavy work. I'm not sure what does the app do, but many factor account for the waiting time, some of which (if not most) are out of your control.

ACTUAL ANSWER

That being said, I guess that the middleware is the best option. You could get the data (IP, user id, etc.) and perform an async call to the database for updating the data. Without awaiting the response from the database, let the request be processed and only when it's done, you await for the response. This will impact relatively the timing, but as mentioned above, there have to be some trade-offs. Even with an external system, you'll have to get the user information along with the IP (and something else?) and then perform a call and wait for it.

EXAMPLE IDEA

You can do something like

from fastapi import FastAPI, Request, Depends
# other imports

app = FastAPI()


@app.middleware("http")
async def record_user_activity(request: Request, user = Depends(get_user), call_next):
    # get user IP and other data
    # do here the call for inserting the data into the db
    # DO NOT AWAIT IT
    response = await call_next(request)
    # NOW AWAIT THE CALL TO THE DB TO MAKE SURE IT HAS FINISHED CORRECTLY
    return response



Answered By - lsabi
Answer Checked By - Katrina (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing