Skip to content
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

Database connection timing out when running fluent queries in parallel #771

Closed
henrypratt opened this issue Dec 12, 2023 · 3 comments
Closed
Labels
duplicate This issue or pull request already exists

Comments

@henrypratt
Copy link

henrypratt commented Dec 12, 2023

I am using TaskGroup to attempt to run fluent queries in parallel, and I keep getting the following error:

[ ERROR ] Connection request (ID 6471 timed out. This might indicate a connection deadlock in your application. If you have long-running requests, consider increasing your connection timeout. [database-id: psql]

Below is a code sample:

        await withTaskGroup(of: Void.self) { group in
            for symbol in symbols {
                group.addTask {
                    do {
                        if let stock = try await Stock.query(on: db)
                            .filter(\.$symbol == symbol)
                            .first() {
                            
                            print(stock.symbol)
                        } else {
                            print("Error")
                        }
                    } catch {
                        fatalError("Caught error!")
                    }
                }
            }
            
            await group.waitForAll()
        }

I am not having this issue with writes, just queries.

@gwynne
Copy link
Member

gwynne commented Dec 12, 2023

This is a known issue caused by issuing a large number of queries in parallel; it will be solved when the new PostgresNIO connection pool module has been adapted for use by all of Fluent. In the meantime, the access pattern you're using is extremely inefficient (especially given that parallelized queries are very rarely advantageous in practice unless your configuration is very heavily tuned)- you can achieve the same effect considerably faster (and with a lot less load on the database) this way:

// It is assumed here that the `symbol` field is a String or other simple type
let stocks: [Stock] = try await Stock
    .query(on: db)
    .filter(\.$symbol ~~ symbols)
    .all()

@gwynne
Copy link
Member

gwynne commented Dec 12, 2023

Duplicate of #716

@gwynne gwynne marked this as a duplicate of #716 Dec 12, 2023
@gwynne gwynne closed this as not planned Won't fix, can't repro, duplicate, stale Dec 12, 2023
@gwynne gwynne added the duplicate This issue or pull request already exists label Dec 12, 2023
@henrypratt
Copy link
Author

Thank you for the fast response! I do not have a lot of experience with databases, so I was unaware that this was inefficient. I need to create a dictionary of UUID's and some other data. So it sound like it would be better to query all stocks, then add their ID's in to a dictionary and keep that in memory?

Also, do you have any recommended reading about why concurrent queries are inefficient and why this pattern should be avoided? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants