-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ReturnTestDatabase does not wipe database before returning to pool #2
Comments
Hi wouterhund, I see, our docs are misleading, we need additional clarification.
So it's actually just an optimization for a very specific use case. Generally, we do not worry about whats happening to the test-databases after their usage. If the pool is exceeded, new test-databases are automatically recreated and assigned anyway. Do you feel that we are missing your specific use case here? |
Ah, I understand! That is an interesting use-case I hadn't considered, and might be able to use to further optimize my tests. When do dirty databases in the pool get recycled? If IntegreSQL does this when the pool is empty, how does IntegreSQL know that the test runner has releases its lock on the database? It seems like it might be possible for an in-use database to be recycled? Or could that only happen if concurrent test runners > pool size? In my testing I noticed that once the pool was empty, then GetTestDatabase started becoming blocking, likely creating the database synchronously. I was hoping I could help PostgreSQL recycle dirty databases early by informing it that they're now no longer used, and was expecting this api call to be used for that. |
Hi, see /pkg/manager/manager.go But you are absolutely right, I think we totally missed having buffered (defaults to Regarding early recycling, that's a pretty relevant use case, we will look into that. -> Feature Request |
After taking a closer look into the recreation mechanism, I can no longer confirm that this is a bug. The buffer mechanism is based on the
Therefore, we always try to have at least However, what could have been happening is that we tried to delete a test database that is still in use, thus failing to free this particular one. Following up on your question:
Yes, this can happen if your We will still take a look at early recycling and the above edge-case anyways... |
Thank you for looking into this! My main issue is about performance sometimes being non-ideal. For context, this is my setup: I am currently using a single test runner, with the default pool size settings (INITIAL=10, MAX=500). But I've also tested with My test runner requires two databases, and thus provisions two templates. This means that before every test Each test takes between 100-200ms, so that's two calls for At this point I was assuming that the pool was depleted, and it was no longer creating new databases in the background and so I created this issue. After digging further into it, I believe that instead IntegreSQL is correctly recycling databases in the background, but that it does so synchronously by locking on the template here: integresql/pkg/manager/manager.go Line 536 in 525f1dc
So my tests are running faster than IntegreSQL is able to create databases. Which makes sense, since creating a database from a template takes about ~500ms in my case and most of my tests are faster than that. And there's hundreds of tests, so it is quite likely that the pool will get depleted during a test run. I have an in-house implementation that I was looking to replace with IntegreSQL. This implementation works similar to approach 3c described in the README, except I'm using 8 background worker threads to recycle dirty databases which doesn't seem to be an issue for PostgreSQL. So, perhaps it is an option to let |
Thanks for your investigation, I understand your concern that the locking mechanism used here is suboptimal for selecting the next ready test database. Nevertheless, are you sure that you are properly closing connections to the pg database between your test runs? Can you check your logs from your PostgreSQL container and see if there are recurrent errors like the following:
I think we generally hold on to the lock for too long as soon as we exceed integresql/pkg/manager/manager.go Lines 542 to 543 in 525f1dc
What's additionally concerning is that if we fail to find an next ready test database, we synchronously return from integresql/pkg/manager/manager.go Lines 288 to 294 in 525f1dc
Will continue to investigate this, but it will potentially take some time (holidays incoming). Feel free to PR in the meantime. |
I am closing them, but only after provisioning the next database if that matters. So before each test run:
I can also confirm that I'm not seeing any errors regarding the database being accessed by other users.
Thank you! I'll keep digging into this as well, but the holidays will soon also take priority 😄 |
Yep, this could actually have an impact, as we try to destroy database as soon as Thanks for you patience, we are also very keen to squeeze out any potential performance gains as well and thus take this issue seriously. |
Closed via #16 |
The documentation says
Which implies the behavior of this call depends on whether true is submitted, but I figure this out.
I was expecting this api call to drop the database and recreate it according to the template and then make it available again.
The text was updated successfully, but these errors were encountered: