Reliably receiving past and future events without duplication
xeruf opened this issue · 13 comments
Is there a way to atomically subscribe to new events and obtain past events matching a certain filter thus that you can be sure not to have missed an event, but also not to receive duplicates?
While we are at it, is there a way to create a subscription that does not receive events submitted by self?
I can use Filter::remove_authors()
, but that would exclude events sent by other programs logged into the same user. Or do I have to manually filter on the client-side, probably with one of those database methods?
And I am a bit confused about auto-closing and dropping subscriptions - do I need to call client.unsubscribe_all
before ending my program or is that implicit on exit? I see no implementation of Drop
so I am a bit dumbstruck.
Also, are the subscriptions in client
only for the current instance of Client
or do they somehow come from the relay and are shared between instances?
I thought about using Filters::new().since
to minimize duplication, but for my application it is totally valid for somebody to sent an event dated in the past, and I still would want to receive that.
Ah I think I got the answer to the original question: client.subscribe
receives old events too.
But Filter::remove_authors
wasn't what I thought, so it seems I have to manually filter out, which unfortunately might incur unnecessary traffic.
do I need to call client.unsubscribe_all before ending my program or is that implicit on exit?
No, when websocket connection is closed, the subscriptions are automatically dropped by the relay
Ah I think I got the answer to the original question: client.subscribe receives old events too.
Yeah, that depends by the filters you set.
While we are at it, is there a way to create a subscription that does not receive events submitted by self?
Yes if using RelayPoolNotification::Event
variant.
To avoid to receive event duplicates you can subscribe and listen for RelayPoolNotification::Event
variant. BUT, the RelayPoolNotification::Event
variant is sent only for the first time the event is seen, so if you query the same filters again you'll not receive again that event notification.
client
.handle_notifications(|notification| async {
if let RelayPoolNotification::Event { event, .. } = notification {
// This notification is sent ONLY the first time the event is seen
}
Ok(false) // Set to true to exit from the loop
})
.await?;
That is what I am already using - but if I run Client::send_event
in another thread, I still get a notification from this.
I would ideally like a subscription that returns me all events except the ones I submitted from this program. Are there negative filters? Then I could maybe use a kind of session-tag.
Ah ok, that shouldn't happen (as specified in RelayPoolNotification::Event
variant docs). I'm going to publish the fix.
Let me know if you still receive events sent by the SDK
Checking right now, but realized I first need to find out how to migrate from 0.30 - especially how to get tag values as I am doing right now: https://forge.ftt.gmbh/janek/mostr/src/branch/main/src/tasks.rs#L104
What is the point of the Arc
there?
A tag can just be cloned easily when needed?
What is the point of the
Arc
there?
Where?
A tag can just be cloned easily when needed?
Yes, the Tag
can be cloned.
i'm seeing similar issues using 0.33.0
. i receive an event notification reliably twice. it appears it comes from two different relays.
loop {
let (event, relay_url) = match notifications.recv().await {
Ok(RelayPoolNotification::Event {
event, relay_url, ..
}) => (event, relay_url),
Ok(RelayPoolNotification::Shutdown) => break,
_ => continue,
};
info!(
"Received event from relay {}: {:?}",
relay_url,
event.as_json()
);
}
this will output a new event at least more than once. this may differ between filters and such, but with my setup, my code is notified twice.
i'm seeing similar issues using
0.33.0
. i receive an event notification reliably twice. it appears it comes from two different relays.loop { let (event, relay_url) = match notifications.recv().await { Ok(RelayPoolNotification::Event { event, relay_url, .. }) => (event, relay_url), Ok(RelayPoolNotification::Shutdown) => break, _ => continue, }; info!( "Received event from relay {}: {:?}", relay_url, event.as_json() ); }this will output a new event at least more than once. this may differ between filters and such, but with my setup, my code is notified twice.
I'll publish v0.34 this week, it'll include the fix for this (commit 5627c40).