-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Implement Postgres LISTEN interface. #98
Conversation
Haven't written any tests for this yet. Happy to do so, but I will have to tackle that over the weekend probably. |
efe0541
to
985265e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good but a few nits.
Re: tests, yes please, whenever it's convenient. |
985265e
to
2955d84
Compare
Ok, addressed all of the review comments and also put together a quick and dirty demo on my local machine to ensure the API was working as needed. Had to update the Only outstanding item at this point is the discussion here: #98 (comment) about buffering of notifications. Should be quite simple to implement, I just want to get some feedback from you guys before moving forward on one of the patterns. Cheers. |
267de3b
to
652f412
Compare
For context on buffering and API design:
My recommendation would be no buffering and prevent external usage of the connection (e.g., remove the derefs). An application could make use of their shared pool to checkout another connection to do work on a notification. My gut says this is the recommended approach when considering high throughput. You don't want to lock up the listening connection by using it for something else. As a a parallel, you don't want to lock up the Here is a theoretical example: let mut listener: PgListener = pool.listen("channel").await?;
while let Some(message) = listener.receive().await? {
// Immediately spawn so we can receive the next message
task::spawn(async move {
// Handle message
})
} API design thoughts:
|
Awesome work so far though @thedodd 🎉 It looks pretty good 💯 . We just need to tweak some of the details I think. |
This comment has been minimized.
This comment has been minimized.
Per some extensive discussion with @mehcode in the discord channel, here is where we landed:
|
e851b66
to
969cb40
Compare
3e28a5f
to
8e7fbba
Compare
pub channel: String, | ||
/// The payload of the notification. | ||
pub payload: String, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mehcode you mentioned some stuff about the structure of this guy in an earlier review. Not sure if this is what you wanted to see. If not, we could just wrap the Box<NotificationResponse>
and provide accessors.
59b2acb
to
4657c48
Compare
4657c48
to
b5bf684
Compare
@@ -4,2268 +4,2275 @@ | |||
name = "aho-corasick" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is all due to an update of the Cargo.lock format ... I'm happy to revert this change (which was unintentional). Not that it is actually used by consumers of this library.
@mehcode && @abonander just wanted to ping you guys to see if you have time for another round of review. I'm happy to start on modifications right away once review is done. I don't want to hold up 0.3 |
pub async fn close(self) -> BoxFuture<'static, Result<()>> { | ||
self.connection.close() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you all think about this, but we could wrap the connection in an Option
so that we can take the connection out and spawn a task to call this close
method from inside of a Drop
impl. That way user's wouldn't have to worry about forgetting to call close
on their own.
With the PgPoolListener
that is easy (already implemented below), as it wraps the current connection in an Option
for internally required reasons.
Thoughts?
@thedodd, Sorry for the radio silence. I'm still working on the 0.3 changes. Hopefully will be opening a PR for it soon. Don't worry about holding up the 0.3 release. We'll get there. |
This changeset introduces an interface for using PostgreSQL's LISTEN functionality from within sqlx. The listen interface is implemented over the PgConnection, PgPool & the PgPoolConnection types for ease of use. In the case of PgPool, a new connection is acquired, and is then used for LISTEN functionality. Closes launchbadge#87
Extension traits are now being used for PgConnection, PgPoolConnection & PgPool for listen/notify functionality. Only two extension traits were introduced. Only a single trait method is present on the extension traits and it works for single or multi channel listening setups. Automatic reconnect behavior is implemented for PgPool based listeners. All logic has been cut over to the `recv` impls for the PgListener variants. Use async-stream for a nice Stream interface.
Broke up PgListener into two types. PgListener for basic one-off connections, and PgPoolListener for the listener created from the PgPool. The API is a bit more clear now with this change in terms of reconnect behavior and the like. Update `fn stream` to be `fn into_stream`, as that nomenclature is a bit more normative in the Rust ecosystem.
The basic PgListener stream impl now yields `Result<PgNotification>` elements without an `Option` in the result. The option condition originally represented the closure of the underlying connection. Now such conditions will terminate the stream, as one would expect. The `PgListener.recv()` method signature has not been changed. PgPoolListener has also been updated. The interfaces on this struct will never yield an inner `Option` as it will instead acquire a new connection and continue its work. Both the stream impl & the `recv` method have received an update to their signatures.
This is being removed as it was causing undesired behavior under some contexts.
7f9b1af
to
4cb0d5d
Compare
@mehcode want me to go ahead and rebase this? I remember you saying something about potentially already having done this while you were testing things out. I'm happy to rebase. |
@thedodd No worries. I'll open a PR with the rebase plus a few ergonomic changes soon and we can discuss there. |
This was merged in via #131 |
This changeset introduces an interface for using PostgreSQL's LISTEN
functionality from within sqlx.
The listen interface is implemented over the PgConnection, PgPool & the
PgPoolConnection types for ease of use. In the case of PgPool, a new
connection is acquired, and is then used for LISTEN functionality.
Closes #87
todo
PgListener
conn is dedicated to receiving notifications only, so ensure it is properly encapsulated.Ext
traits for everything..listen(&[&str])
interface onPgConnection
,PgPoolConnection
&PgPool
(covers single & multi channel).PgListener
in a singlereceive
method.PgPool
.Stream
in terms ofreceive
.