Skip to content

Commit cd41b1c

Browse files
committed
WIP: refactor relay support into subman
Is currently in notedeck_columns::app
1 parent e0bef72 commit cd41b1c

File tree

2 files changed

+154
-94
lines changed

2 files changed

+154
-94
lines changed

crates/notedeck/src/subman.rs

+83-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::collections::BTreeMap;
33
use std::fmt;
44
use std::{cell::RefCell, cmp::Ordering, rc::Rc};
55
use thiserror::Error;
6+
use tracing::{error, info, trace, warn};
67
use uuid::Uuid;
78

8-
use enostr::{Filter, RelayPool};
9+
use enostr::{Filter, PoolRelay, RelayEvent, RelayMessage, RelayPool};
910
use nostrdb::{self, Ndb, Subscription, SubscriptionStream};
1011

1112
/// The Subscription Manager
@@ -292,6 +293,84 @@ impl SubMan {
292293

293294
Ok((maybe_tx_eose, SubReceiver { lclsub, rmtsub }))
294295
}
296+
297+
pub fn process_relays<H: LegacyRelayHandler>(
298+
&mut self,
299+
legacy_relay_handler: &mut H,
300+
) -> SubResult<()> {
301+
let wakeup = move || {
302+
// ignore
303+
};
304+
self.pool.keepalive_ping(wakeup);
305+
306+
// NOTE: we don't use the while let loop due to borrow issues
307+
#[allow(clippy::while_let_loop)]
308+
loop {
309+
let ev = if let Some(ev) = self.pool.try_recv() {
310+
ev.into_owned()
311+
} else {
312+
break;
313+
};
314+
315+
match (&ev.event).into() {
316+
RelayEvent::Opened => {
317+
legacy_relay_handler.handle_opened(&ev.relay);
318+
}
319+
// TODO: handle reconnects
320+
RelayEvent::Closed => warn!("{} connection closed", &ev.relay),
321+
RelayEvent::Error(e) => error!("{}: {}", &ev.relay, e),
322+
RelayEvent::Other(msg) => trace!("other event {:?}", &msg),
323+
RelayEvent::Message(msg) => {
324+
self.process_message(legacy_relay_handler, &ev.relay, &msg);
325+
}
326+
}
327+
}
328+
Ok(())
329+
}
330+
331+
pub fn process_message<H: LegacyRelayHandler>(
332+
&mut self,
333+
legacy_relay_handler: &mut H,
334+
relay: &str,
335+
msg: &RelayMessage,
336+
) {
337+
match msg {
338+
RelayMessage::Event(_subid, ev) => {
339+
let relay = if let Some(relay) = self.pool.relays.iter().find(|r| r.url() == relay)
340+
{
341+
relay
342+
} else {
343+
error!("couldn't find relay {} for note processing!?", relay);
344+
return;
345+
};
346+
347+
match relay {
348+
PoolRelay::Websocket(_) => {
349+
//info!("processing event {}", event);
350+
if let Err(err) = self.ndb.process_event(ev) {
351+
error!("error processing event {ev}: {err}");
352+
}
353+
}
354+
PoolRelay::Multicast(_) => {
355+
// multicast events are client events
356+
if let Err(err) = self.ndb.process_client_event(ev) {
357+
error!("error processing multicast event {ev}: {err}");
358+
}
359+
}
360+
}
361+
}
362+
RelayMessage::Notice(msg) => warn!("Notice from {}: {}", relay, msg),
363+
RelayMessage::OK(cr) => info!("OK {:?}", cr),
364+
RelayMessage::Eose(sid) => {
365+
legacy_relay_handler.handle_eose(sid, relay);
366+
}
367+
}
368+
}
369+
}
370+
371+
pub trait LegacyRelayHandler {
372+
fn handle_opened(&mut self, relay: &str);
373+
fn handle_eose(&mut self, sid: &str, relay: &str);
295374
}
296375

297376
struct LclSub {
@@ -359,9 +438,9 @@ impl SubReceiver {
359438
// only remote sub (prefetch only, values not returned)
360439
match rsub.rmteose.next().await {
361440
Some(_) => Err(SubError::StreamEnded),
362-
None => Err(SubError::InternalError(format!(
363-
"trouble reading from rmteose"
364-
))),
441+
None => Err(SubError::InternalError(
442+
"trouble reading from rmteose".to_string(),
443+
)),
365444
}
366445
} else {
367446
// query case

crates/notedeck_columns/src/app.rs

+71-90
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use crate::{
1414
};
1515

1616
use notedeck::{
17-
Accounts, AppContext, DataPath, DataPathType, FilterState, ImageCache, SubError, SubMan,
18-
UnknownIds,
17+
subman::LegacyRelayHandler, Accounts, AppContext, DataPath, DataPathType, FilterState,
18+
ImageCache, SubError, SubMan, UnknownIds,
1919
};
2020

21-
use enostr::{ClientMessage, Keypair, PoolRelay, Pubkey, RelayEvent, RelayMessage};
21+
use enostr::{ClientMessage, Keypair, Pubkey};
2222
use uuid::Uuid;
2323

2424
use egui_extras::{Size, StripBuilder};
@@ -28,7 +28,7 @@ use nostrdb::{Ndb, Transaction};
2828
use std::collections::{BTreeSet, HashMap};
2929
use std::path::Path;
3030
use std::time::Duration;
31-
use tracing::{debug, error, info, trace, warn};
31+
use tracing::{debug, error, info, warn};
3232

3333
#[derive(Debug, Eq, PartialEq, Clone)]
3434
pub enum DamusState {
@@ -83,53 +83,78 @@ fn handle_key_events(input: &egui::InputState, columns: &mut Columns) {
8383
}
8484
}
8585

86-
fn try_process_event(
87-
damus: &mut Damus,
88-
app_ctx: &mut AppContext<'_>,
86+
struct RelayHandler<'a> {
87+
app_ctx: &'a mut AppContext<'a>,
88+
subscriptions: &'a mut Subscriptions,
89+
timeline_cache: &'a mut TimelineCache,
90+
since_optimize: bool,
91+
}
92+
93+
impl<'a> RelayHandler<'a> {
94+
fn new(
95+
app_ctx: &'a mut AppContext<'a>,
96+
subscriptions: &'a mut Subscriptions,
97+
timeline_cache: &'a mut TimelineCache,
98+
since_optimize: bool,
99+
) -> Self {
100+
RelayHandler {
101+
app_ctx,
102+
subscriptions,
103+
timeline_cache,
104+
since_optimize,
105+
}
106+
}
107+
}
108+
109+
impl<'a> LegacyRelayHandler for RelayHandler<'a> {
110+
/// Handle relay opened
111+
fn handle_opened(&mut self, relay: &str) {
112+
self.app_ctx
113+
.accounts
114+
.send_initial_filters(self.app_ctx.subman.pool(), relay);
115+
timeline::send_initial_timeline_filters(
116+
self.app_ctx.ndb,
117+
self.since_optimize,
118+
self.timeline_cache,
119+
self.subscriptions,
120+
self.app_ctx.subman.pool(),
121+
relay,
122+
);
123+
}
124+
125+
/// Handle end-of-stored-events
126+
fn handle_eose(&mut self, sid: &str, relay: &str) {
127+
if let Err(_) = handle_eose(
128+
&*self.subscriptions,
129+
self.timeline_cache,
130+
self.app_ctx,
131+
sid,
132+
relay,
133+
) {
134+
// already logged ...
135+
}
136+
}
137+
}
138+
139+
fn try_process_event<'a>(
140+
damus: &'a mut Damus,
141+
app_ctx: &'a mut AppContext<'a>,
89142
ctx: &egui::Context,
90143
) -> Result<()> {
91144
let current_columns = get_active_columns_mut(app_ctx.accounts, &mut damus.decks_cache);
92145
ctx.input(|i| handle_key_events(i, current_columns));
93146

94-
let ctx2 = ctx.clone();
95-
let wakeup = move || {
96-
ctx2.request_repaint();
97-
};
98-
99-
app_ctx.subman.pool().keepalive_ping(wakeup);
100-
101-
// NOTE: we don't use the while let loop due to borrow issues
102-
#[allow(clippy::while_let_loop)]
103-
loop {
104-
let ev = if let Some(ev) = app_ctx.subman.pool().try_recv() {
105-
ev.into_owned()
106-
} else {
107-
break;
108-
};
109-
110-
match (&ev.event).into() {
111-
RelayEvent::Opened => {
112-
app_ctx
113-
.accounts
114-
.send_initial_filters(app_ctx.subman.pool(), &ev.relay);
115-
116-
timeline::send_initial_timeline_filters(
117-
app_ctx.ndb,
118-
damus.since_optimize,
119-
&mut damus.timeline_cache,
120-
&mut damus.subscriptions,
121-
app_ctx.subman.pool(),
122-
&ev.relay,
123-
);
124-
}
125-
// TODO: handle reconnects
126-
RelayEvent::Closed => warn!("{} connection closed", &ev.relay),
127-
RelayEvent::Error(e) => error!("{}: {}", &ev.relay, e),
128-
RelayEvent::Other(msg) => trace!("other event {:?}", &msg),
129-
RelayEvent::Message(msg) => {
130-
process_message(damus, app_ctx, &ev.relay, &msg);
131-
}
132-
}
147+
{
148+
let mut relay_handler = RelayHandler::new(
149+
app_ctx,
150+
&mut damus.subscriptions,
151+
&mut damus.timeline_cache,
152+
damus.since_optimize,
153+
);
154+
relay_handler
155+
.app_ctx
156+
.subman
157+
.process_relays(&mut relay_handler);
133158
}
134159

135160
for (_kind, timeline) in damus.timeline_cache.timelines.iter_mut() {
@@ -139,7 +164,6 @@ fn try_process_event(
139164
app_ctx.note_cache,
140165
timeline,
141166
);
142-
143167
if is_ready {
144168
let txn = Transaction::new(app_ctx.ndb).expect("txn");
145169
// only thread timelines are reversed
@@ -162,7 +186,6 @@ fn try_process_event(
162186
if app_ctx.unknown_ids.ready_to_send() {
163187
unknown_id_send(app_ctx.unknown_ids, app_ctx.subman);
164188
}
165-
166189
Ok(())
167190
}
168191

@@ -310,48 +333,6 @@ fn handle_eose(
310333
Ok(())
311334
}
312335

313-
fn process_message(damus: &mut Damus, ctx: &mut AppContext<'_>, relay: &str, msg: &RelayMessage) {
314-
match msg {
315-
RelayMessage::Event(_subid, ev) => {
316-
let relay =
317-
if let Some(relay) = ctx.subman.pool().relays.iter().find(|r| r.url() == relay) {
318-
relay
319-
} else {
320-
error!("couldn't find relay {} for note processing!?", relay);
321-
return;
322-
};
323-
324-
match relay {
325-
PoolRelay::Websocket(_) => {
326-
//info!("processing event {}", event);
327-
if let Err(err) = ctx.ndb.process_event(ev) {
328-
error!("error processing event {ev}: {err}");
329-
}
330-
}
331-
PoolRelay::Multicast(_) => {
332-
// multicast events are client events
333-
if let Err(err) = ctx.ndb.process_client_event(ev) {
334-
error!("error processing multicast event {ev}: {err}");
335-
}
336-
}
337-
}
338-
}
339-
RelayMessage::Notice(msg) => warn!("Notice from {}: {}", relay, msg),
340-
RelayMessage::OK(cr) => info!("OK {:?}", cr),
341-
RelayMessage::Eose(sid) => {
342-
if let Err(err) = handle_eose(
343-
&damus.subscriptions,
344-
&mut damus.timeline_cache,
345-
ctx,
346-
sid,
347-
relay,
348-
) {
349-
error!("error handling eose: {}", err);
350-
}
351-
}
352-
}
353-
}
354-
355336
fn render_damus(damus: &mut Damus, app_ctx: &mut AppContext<'_>, ui: &mut egui::Ui) {
356337
if notedeck::ui::is_narrow(ui.ctx()) {
357338
render_damus_mobile(damus, app_ctx, ui);

0 commit comments

Comments
 (0)