Skip to content

Improve performance and make JWT auth non-blocking#59

Merged
tekrajchhetri merged 7 commits intomainfrom
user_management
Feb 6, 2026
Merged

Improve performance and make JWT auth non-blocking#59
tekrajchhetri merged 7 commits intomainfrom
user_management

Conversation

@tekrajchhetri
Copy link
Collaborator

@tekrajchhetri tekrajchhetri commented Jan 12, 2026

This pull requests updates the code to make it async/non-blocking to address the following issue sensein/brainkb-ui#101.

Test System
Apple M3 Pro/36GB RAM/12 Cores

MLService Test
Total requests: 5000 with 100 concurrent requests
Success (2xx): 4982 (99.64%)
Failures: 18 (0.36%)
Latency ms: min=19.83 avg=3533.93 max=10118.82 p50=3510.18 p90=4259.24 p95=4506.85 p99=5305.97

Status counts:
200: 4982
NO_STATUS: 18

Test results:
latency_ecdf
latency_over_time
status_counts
latency_hist

Queryservice
Total requests: 5000
Success (2xx): 5000 (100.00%)
Failures: 0 (0.00%)
Latency ms: min=655.10 avg=3402.47 max=8468.60 p50=3358.82 p90=4232.98 p95=4568.08 p99=5212.95

Test results:
latency_ecdf
latency_hist
latency_over_time
status_counts

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @tekrajchhetri, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the performance and scalability of the JWT authentication system by transforming blocking operations into non-blocking asynchronous calls. By leveraging asyncio.to_thread for CPU-intensive tasks like password handling and adopting an asynchronous database connection pattern, the application can now handle more concurrent requests without performance degradation, directly addressing the identified issue of blocking behavior.

Highlights

  • Asynchronous Password Operations: Converted synchronous password hashing and verification functions (get_password_hash, verify_password) to asynchronous using asyncio.to_thread to prevent blocking the event loop during CPU-bound operations.
  • Non-blocking Database Connections in Auth Routes: Updated JWT authentication routes (/register, /token) to utilize an asynchronous database connection context manager (async with get_db_connection()) for improved non-blocking I/O and proper connection management.
  • Refactored Database Dependency: Replaced the connect_postgres dependency injection with direct asynchronous database connection management within the authentication endpoints, aligning with the non-blocking approach.
  • Documentation Cleanup: Removed an outdated 'Troubleshooting' section from the readme.md file.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great step forward in making the JWT authentication logic fully non-blocking. The use of asyncio.to_thread for CPU-bound tasks like password hashing is correctly implemented, and the switch to an async with context manager for database connections significantly improves resource management. My review focuses on a potential race condition in the user registration flow and suggests adding return type hints to enhance code clarity and maintainability. Overall, these are excellent changes that improve the application's performance and robustness.

@tekrajchhetri tekrajchhetri changed the title Make JWT auth non-blocking Improve performance and make JWT auth non-blocking Jan 13, 2026
@djarecka
Copy link
Contributor

Hi @tekrajchhetri - do I understand correctly, that you believe that the issues with content loading was due to the authentications issues. And since query and ml services used the same method, it was affecting both.

Thank you for creating plots. These plots are after your changes, correct? It would be nice to see how your changes have improved the times, do you have the plots before your changes?

Also, I understand that you run your testing/plotting functions twice, for different url (and not for the default one that is http://localhost:8007/api/token, am I right? Maybe you can share how you run it.
Does it also make sense to check GET?

@tekrajchhetri
Copy link
Collaborator Author

tekrajchhetri commented Jan 29, 2026

There's a script that I ran for this that you can look at test/load_test_token_endpoint.py. It's tested for two different microservices.

Regarding the problem, I have created an issue sensein/brainkb-ui#101. To answer your question, its not authentication issue but the database issue--connection was not released and was problematic when there're more connections--that was causing the authentication problem.

@djarecka
Copy link
Contributor

djarecka commented Feb 3, 2026

There's a script that I ran for this that you can look at test/load_test_token_endpoint.py. It's tested for two different microservices.

Yes, I saw the script, but if you can provide the arguments you used to run it would allow to comapre.

Also, I asked if by any chance you run the scripts before and after changes?

Another question was if it makes sense to test GET, not only POST (at least for some services)

Regarding the problem, I have created an issue sensein/brainkb-ui#101. To answer your question, its not authentication issue but the database issue--connection was not released and was problematic when there're more connections--that was causing the authentication problem.

Yes, I saw the issue about loading the data, but I understand that you found out that the process of the authentication was responsible for it (not the query service)

@tekrajchhetri
Copy link
Collaborator Author

yes, but the test result includes both mlservice and query service. Regarding the configuration I ran with the default one, i.e., the one present in test file.

Steps to test:

  1. Deploy BrainKB
  2. Setup the API, i.e., credentials
  3. Update test file accordingly to correct API endpoints, credentials...
  4. Run the script.

@tekrajchhetri
Copy link
Collaborator Author

@djarecka any update on this?

@djarecka
Copy link
Contributor

djarecka commented Feb 6, 2026

Hi @tekrajchhetri - I really try to understand the meaning and importance of the statistics you plotted, so please answer the questions I've been asking (and if the question is not clear, let me know, I can clarify):

  1. can you please provide the arguments you used to run the script.

  2. Have you run the scripts before and after the changes? (Were these really good tests to identify the issue and see the improvements?)

  3. (related to 2) I'm wondering if you also tried GET not only POST (and how testing this might be useful)

@tekrajchhetri
Copy link
Collaborator Author

@djarecka I said, I used the default configuration parameters that's in the script. I am not sure why you are still asking for arguments. Did you check the code to see what are the default arguments, if not please check the configuration parameters here --

def parse_args() -> argparse.Namespace:
?

Regarding how this testing is useful? You did see the issue with the current website. It tests under load if the login works properly with no database issue. And no I did not ran the test code before, only after fix.

@djarecka
Copy link
Contributor

djarecka commented Feb 6, 2026

@djarecka I said, I used the default configuration parameters that's in the script. I am not sure why you are still asking for arguments. Did you check the code to see what are the default arguments, if not please check the configuration parameters here --

def parse_args() -> argparse.Namespace:

just to clarify, when you mean that you run "the default arguments" and "Update test file accordingly to correct API endpoints", you mean the url argument, correct? So that would be equivalent to running with arguments --url http://localhost:8010/api/token for query service?

?
Regarding how this testing is useful? You did see the issue with the current website. It tests under load if the login works properly with no database issue. And no I did not ran the test code before, only after fix.

You can merge this PR, but in the future I would like us to think more about what we call a "test". If someone fixes an issue and adds a test, I would expect that the test could be (and was) used to show the difference before and after the fix.

I do understand that testing UI is not that easy, and we should add more test in the future. Because I want to work on this, I tried to understand the importance of the plots, but we can come back to this later.

@tekrajchhetri
Copy link
Collaborator Author

@djarecka I am merging this request. Just to clarify, it's not UI testing. Also, the URL would be http://localhost:8010/api/token and http://localhost:8007/api/token for query service and ML service respectively. I thought you'd take the full context into account as in the starting of this request, it's mentioned what all services were tested and you're also aware of these services.

Yes, we can discuss about testing and other things in the meeting.

@tekrajchhetri tekrajchhetri reopened this Feb 6, 2026
@tekrajchhetri tekrajchhetri merged commit 82d2de8 into main Feb 6, 2026
@djarecka
Copy link
Contributor

djarecka commented Feb 6, 2026

@djarecka I am merging this request. Just to clarify, it's not UI testing.

yes, I know. I was writing this about BrainKB in general.

Also, the URL would be http://localhost:8010/api/token and http://localhost:8007/api/token for query service and ML service respectively. I thought you'd take the full context into account as in the starting of this request, it's mentioned what all services were tested and you're also aware of these services.

I'm glad we agree on the argument you used. I would just ask for the future, if we are adding plots to PR with any kind of metrics, we simply add the commands that were used to generate them and the description.
Not because the reviewer can't figure it out, but just so it's clear right away for everyone. I never said that I didn't know how you created the figures, I was simply asking to add it in the description of the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants