-
Notifications
You must be signed in to change notification settings - Fork 8
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
Query history from history server #143
Conversation
8c1f8ed
to
b7369a8
Compare
@spb AFAICT, I only need to implement AROUND in the postgresql backend before this PR is ready to be merged. Could you start reviewing? |
|
||
let mut connection_lock = self.database_connection.lock().await; | ||
|
||
let db_channel_id = i64::try_from(channel_id.as_u64()).expect("channel id overflows u64"); |
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've been preferring as
conversions for this (to be replaced eventually with cast_signed/cast_unsigned), to just store and retrieve the bit pattern on the basis that we don't need the database server to be ordering IDs, just checking equality.
Unless we do need the database to order them, in which case we need to change the existing code (and should probably enforce on creation that an id fits in 63 bits). Either way I think it's better to be consistent.
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.
ok for now, but in the future we should do it explicitly, eg. with bytemuck. Behavior of as
depends on compilation profile, so it shouldn't be relied upon.
return HashMap::new(); | ||
} | ||
Ok(rows) => { | ||
rows.map(|row| row.expect("Could not deserialize row")) |
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.
Is panicking appropriate here or should we log an error and skip instead? We've got a lot of existing PoC code that panics all over the place but maybe it's time to make more efforts not to.
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.
Based on https://docs.rs/diesel/latest/diesel/result/enum.Error.html this happens when:
- there is a major logic error on our side,
- the database misbehaved, or
- the database schema does not match Rust's
It seems reasonable to crash either way.
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.
Heh, you're right. I removed the panics.
historic_users::dsl::ident, | ||
historic_users::dsl::vhost, | ||
historic_users::dsl::account_name, | ||
)) |
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.
Is it worth packaging this query up into a helper function in the models?
@@ -27,7 +29,7 @@ pub struct HistoryServerConfig { | |||
pub struct HistoryServer { | |||
node: Arc<NetworkNode>, | |||
history_receiver: Mutex<UnboundedReceiver<sable_network::rpc::NetworkHistoryUpdate>>, | |||
database_connection: Mutex<AsyncPgConnection>, | |||
database_connection: Mutex<AsyncPgConnection>, // TODO: use a connection pool |
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.
Yes, definitely
@@ -20,12 +22,12 @@ fn target_id_for_entry(for_user: UserId, entry: &HistoryLogEntry) -> Option<Targ | |||
} | |||
|
|||
/// Implementation of [`HistoryService`] backed by [`NetworkNode`] | |||
pub struct LocalHistoryService<'a> { | |||
node: &'a NetworkNode, | |||
pub struct LocalHistoryService<'a, NetworkPolicy: policy::PolicyService> { |
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'm starting to really question whether making Node generic over its policy was a good idea. Not much to do about it in this PR but it wants thought more generally.
)) | ||
.filter(messages::dsl::target_channel.eq(db_channel_id)); | ||
Ok(match request { | ||
HistoryRequest::Latest { to_ts, limit } => { |
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.
Is there no commonality in these arms that can be broken out? They're quite hard to follow as they are.
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 can rewrite Latest/Before/After as a Between, I guess
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 managed to deduplicate most of the code: a8f711b
|
||
fn make_historical_event( | ||
channel: &crate::models::Channel, | ||
(id, timestamp, message_type, text, source_nick, source_ident, source_vhost, source_account): ( |
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.
This might be more readable as a new Queryable struct (possibly with a helper method in the model to query it) - this ties into the comment further up about a helper query method
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 don't see what you have in mind
async fn handle_new_message( | ||
&self, | ||
new_message: update::NewMessage, | ||
update_timestamp: i64, |
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.
Why is this not using the ts field from the Message?
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.
To make the @time
tag consistent between echo-message and chathistory d56db83
pub sasl_mechanisms: Vec<String>, | ||
} | ||
|
||
#[target_type(ServerId)] | ||
struct IntroduceHistoryServer { |
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 realise this is matching the services behaviour and it's probably fine for now, but long term the desired behaviour isn't the same - we need a single authoritative services node, but for history we can have multiple active nodes and just send requests to any of them.
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.
ack
test suite here: progval/irctest#292