bergey / preql

experiments with SQL & Haskell
BSD 3-Clause "New" or "Revised" License
13 stars 0 forks source link

defer decoding until after connection is returned to pool? #7

Open bergey opened 4 years ago

bergey commented 4 years ago

In an application with a connection pool, @jfischoff has suggested that it would be better to postpone decoding rows until after the connection is returned to the pool. Can we put together a SQL instance that does so?

If we’re in the middle of a transaction, we need to hold the connection while decoding (assuming the decoded values are used) If we’re at the end of a transaction, we’d like to return the connection to the pool, decode, then return from runTransaction I don’t know how to tell whether there are any more statements coming in a do-block; that seems hard with a monad. Maybe we can do something more restrictive, like Applicative?

Maybe an easier approach is lazy decoding. Decoding can fail, and I suspect users still want decoding errors to cause an exception in runTransaction, not later. Maybe we can force any deferred decoding in runTransaction after returning the connection to a pool? That might also let us make field-by-field decisions about decoding intermediate results. I have not delved into libpq enough to verify that the Result is safe to use while other threads are using the Connection that produced it. Need to do that, or copy all the bytestrings out of the Result before returning the Connection to the Pool - which seems likely to overwhelm any time savings.

bergey commented 3 years ago

Benchmarking showed that getvalue' is faster than the version that does not copy the bytestring. So copying all the bytestrings and doing further decoding later (eg, JSON parsing) might be a viable approach.

bergey commented 3 years ago

I pushed a branch that (I think) makes decoding lazy. The benchmarks do not show any savings, likely because the variance in running the query swamps the savings. I don't want to make this change without supporting benchmarks, so I'm waiting for a better benchmark design.

simfleischman commented 3 years ago

I wonder if you could create a decoder that takes an artificially long time in order to make the decoding time greater than the query time?

bergey commented 3 years ago

I don't want something totally contrived, like a decoder that sleeps. Maybe a sufficiently large JSON payload would show the effect we're interested in?