Open alexnivanov opened 1 year ago
Technically, one connection cannot run multiple queries in parallel. I think what you are asking for is pipelining.
And you are partially in luck. Pipeline support is available in pgconn: https://pkg.go.dev/github.com/jackc/pgx/v5@v5.0.3/pgconn#Pipeline. However, that is a much lower level interface. pgx uses pipelining to implement batch support but does expose pipelining directly. pgx does provide the helper function RowsFromResultReader
to aid 3rd party integrations.
There are a number of issues involved that make a one size fits all high level pipelined query API difficult to design. Just a few of which are:
I wouldn't rule out adding it to core pgx, but finding a broadly usable API might be tricky. I'd probably want to see a 3rd party implementation and get some user experience reports.
But the idea is to use multiple connections! Like in my code snippet we acquire connection for each query, and they can run in parallel.
I got this pattern from Slick (https://scala-slick.org), where there's actually a pool of ~20 DB connections, and all DB queries return Future result (somewhat similar to Golang channel) to allow for parallel execution.
But the idea is to use multiple connections! Like in my code snippet we acquire connection for each query, and they can run in parallel.
So you just want to run multiple queries 1 to 1 with connections (i.e. no pipelining)? Then I don't understand how pgxpool.Pool
and goroutines aren't enough.
Well, they are enough, you just have to write a lot of boilerplate code which seems to be inseparable from the framework.
🤷 AFAICT there is nothing that would need to change in core pgx to allow this in a 3rd party library.
That said, I suppose it might be convenient to have this sort of thing in core. So I guess if someone wants to try this I would be open to merging it, but I don't have any immediate plans to do it myself.
Also, even though your request is simpler than I originally thought, there are still edge cases and some interesting API design decisions to make such as:
What would be the interface? Channels, promises, something like the current batch system, etc.?
For a really crazy idea, I could almost see some sort of query executor / manager that could handle parallel queries like you requested here, and automatic pipelining like I originally thought you wanted, along with batching and normal queries. Might be too complicated, but the idea of something that you can throw a bunch of queries at and it figures out how best to execute them is intriguing. 🤔
As for more complex manager with pipelining - well sounds cool, but my expertise doesn't go that far :)
Btw: I googled and found this library which is very similar to what I wanted: https://github.com/naoina/asynql Perhaps I'd create a similar library for pgx...
Is your feature request related to a problem? Please describe. There's a simple use case: run several DB queries in parallel instead of sequentially for better response time.
Describe the solution you'd like I've create a wrapper like this:
(handler function does actual querying synchronously).
Then it's possible to combine 2 (and more) queries like this:
The task of querying DB asynchronously seems to be a must have in modern times...