bikeshedder / deadpool

Dead simple pool implementation for rust with async-await
Apache License 2.0
1.08k stars 137 forks source link

Support PostgreSQL notifications. #360

Open lvella opened 1 month ago

lvella commented 1 month ago

I need to receive PostgreSQL asynchronous notifications in my application.

At ConfigConnectImpl<T>::connect() , a task is created awaiting for the tokio-postgres connection to run to completion. This discards every notification received by the client.

Instead of simple await on the connection, deadpool-postgres could use tokio_postgres::Connection<S, T>::poll_message() to received notifications. It could buffer them a VecDeque, like the synchronous postgres wrapper around tokio-postgres does it. Or at least allow us to register a callback, for the duration of the borrow, to handle them.

bikeshedder commented 1 month ago

How about pushing messages to a tokio::sync::mpsc (or broadcast?) channel? I just think there should be a security measure in place. e.g. returning the connection to the pool will close this channel and upon recycling the connection a new empty channel is created.

When recycling the connection it's also important to execute a UNLISTEN * statement so those unused resources are cleared.

Apart from those technical details I'm curious if this is really the right way to do it. A better aproach would be to create one connection to the database and issue all LISTEN statements there. Am I missing a usecase that is not possible with that approach?

lvella commented 1 month ago

Yes, I ended up writing my own connection pool, and used a tokio::sync::mpsc channel for the messages.

In my application, the notification is task specific: get a connection from the pool, do some writes, write to a channel, wait on for the response in the channel specific to the thing that was written, do some read, return the connection to the pool. The receiving channel will never be used again, or by other client.