retroactively fix bad data in roomuserid_joined
, remove pointless prefix scans
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
0524e6ed52
commit
ccf9f95cc9
3 changed files with 117 additions and 20 deletions
|
@ -10,13 +10,13 @@ use conduit::{debug_info, debug_warn};
|
||||||
use database::KeyValueDatabase;
|
use database::KeyValueDatabase;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
events::{push_rules::PushRulesEvent, GlobalAccountDataEventType},
|
events::{push_rules::PushRulesEvent, room::member::MembershipState, GlobalAccountDataEventType},
|
||||||
push::Ruleset,
|
push::Ruleset,
|
||||||
EventId, OwnedRoomId, RoomId, UserId,
|
EventId, OwnedRoomId, RoomId, UserId,
|
||||||
};
|
};
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
use crate::{services, utils, Config, Error, Result};
|
use crate::{globals::data::Data, services, utils, Config, Error, Result};
|
||||||
|
|
||||||
pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result<()> {
|
pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result<()> {
|
||||||
// Matrix resource ownership is based on the server name; changing it
|
// Matrix resource ownership is based on the server name; changing it
|
||||||
|
@ -555,6 +555,9 @@ pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result
|
||||||
{
|
{
|
||||||
warn!("Fixing bad double separator in state_cache roomuserid_joined");
|
warn!("Fixing bad double separator in state_cache roomuserid_joined");
|
||||||
let mut iter_count: usize = 0;
|
let mut iter_count: usize = 0;
|
||||||
|
|
||||||
|
let _cork = db.cork();
|
||||||
|
|
||||||
for (mut key, value) in db.roomuserid_joined.iter() {
|
for (mut key, value) in db.roomuserid_joined.iter() {
|
||||||
iter_count = iter_count.saturating_add(1);
|
iter_count = iter_count.saturating_add(1);
|
||||||
debug_info!(%iter_count);
|
debug_info!(%iter_count);
|
||||||
|
@ -575,10 +578,101 @@ pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.cleanup()?;
|
||||||
|
|
||||||
|
warn!("Finished fixing");
|
||||||
|
|
||||||
db.global
|
db.global
|
||||||
.insert(b"fix_bad_double_separator_in_state_cache", &[])?;
|
.insert(b"fix_bad_double_separator_in_state_cache", &[])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if db
|
||||||
|
.global
|
||||||
|
.get(b"retroactively_fix_bad_data_from_roomuserid_joined")?
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
warn!("Retroactively fixing bad data from broken roomuserid_joined");
|
||||||
|
|
||||||
|
let room_ids = services()
|
||||||
|
.rooms
|
||||||
|
.metadata
|
||||||
|
.iter_ids()
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let _cork = db.cork();
|
||||||
|
|
||||||
|
for room_id in room_ids.clone() {
|
||||||
|
debug_info!("Fixing room {room_id}");
|
||||||
|
|
||||||
|
let users_in_room = services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.room_members(&room_id)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let joined_members = users_in_room
|
||||||
|
.iter()
|
||||||
|
.filter(|user_id| {
|
||||||
|
services()
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.get_member(&room_id, user_id)
|
||||||
|
.unwrap_or(None)
|
||||||
|
.map_or(false, |membership| membership.membership == MembershipState::Join)
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let non_joined_members = users_in_room
|
||||||
|
.iter()
|
||||||
|
.filter(|user_id| {
|
||||||
|
services()
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.get_member(&room_id, user_id)
|
||||||
|
.unwrap_or(None)
|
||||||
|
.map_or(false, |membership| {
|
||||||
|
membership.membership == MembershipState::Leave
|
||||||
|
|| membership.membership == MembershipState::Ban
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
for user_id in joined_members {
|
||||||
|
debug_info!("User is joined, marking as joined");
|
||||||
|
services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.mark_as_joined(user_id, &room_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
for user_id in non_joined_members {
|
||||||
|
debug_info!("User is left or banned, marking as left");
|
||||||
|
services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.mark_as_left(user_id, &room_id)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for room_id in room_ids {
|
||||||
|
debug_info!(
|
||||||
|
"Updating joined count for room {room_id} to fix servers in room after correcting membership \
|
||||||
|
states"
|
||||||
|
);
|
||||||
|
|
||||||
|
services().rooms.state_cache.update_joined_count(&room_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.cleanup()?;
|
||||||
|
|
||||||
|
warn!("Finished fixing");
|
||||||
|
|
||||||
|
db.global
|
||||||
|
.insert(b"retroactively_fix_bad_data_from_roomuserid_joined", &[])?;
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
services().globals.database_version().unwrap(),
|
services().globals.database_version().unwrap(),
|
||||||
latest_database_version,
|
latest_database_version,
|
||||||
|
@ -648,6 +742,8 @@ pub(crate) async fn migrations(db: &KeyValueDatabase, config: &Config) -> Result
|
||||||
|
|
||||||
db.global
|
db.global
|
||||||
.insert(b"fix_bad_double_separator_in_state_cache", &[])?;
|
.insert(b"fix_bad_double_separator_in_state_cache", &[])?;
|
||||||
|
db.global
|
||||||
|
.insert(b"retroactively_fix_bad_data_from_roomuserid_joined", &[])?;
|
||||||
|
|
||||||
// Create the admin room and server user on first run
|
// Create the admin room and server user on first run
|
||||||
services().admin.create_admin_room().await?;
|
services().admin.create_admin_room().await?;
|
||||||
|
|
|
@ -130,14 +130,7 @@ impl Data for KeyValueDatabase {
|
||||||
self.userroomid_leftstate.remove(&userroom_id)?;
|
self.userroomid_leftstate.remove(&userroom_id)?;
|
||||||
self.roomuserid_leftcount.remove(&roomuser_id)?;
|
self.roomuserid_leftcount.remove(&roomuser_id)?;
|
||||||
|
|
||||||
if self.roomuserid_joined.scan_prefix(roomid.clone()).count() == 0
|
|
||||||
&& self
|
|
||||||
.roomuserid_invitecount
|
|
||||||
.scan_prefix(roomid.clone())
|
|
||||||
.count() == 0
|
|
||||||
{
|
|
||||||
self.roomid_inviteviaservers.remove(&roomid)?;
|
self.roomid_inviteviaservers.remove(&roomid)?;
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -206,14 +199,7 @@ impl Data for KeyValueDatabase {
|
||||||
self.userroomid_invitestate.remove(&userroom_id)?;
|
self.userroomid_invitestate.remove(&userroom_id)?;
|
||||||
self.roomuserid_invitecount.remove(&roomuser_id)?;
|
self.roomuserid_invitecount.remove(&roomuser_id)?;
|
||||||
|
|
||||||
if self.roomuserid_joined.scan_prefix(roomid.clone()).count() == 0
|
|
||||||
&& self
|
|
||||||
.roomuserid_invitecount
|
|
||||||
.scan_prefix(roomid.clone())
|
|
||||||
.count() == 0
|
|
||||||
{
|
|
||||||
self.roomid_inviteviaservers.remove(&roomid)?;
|
self.roomid_inviteviaservers.remove(&roomid)?;
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -654,8 +640,7 @@ impl Data for KeyValueDatabase {
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
fn servers_invite_via(&self, room_id: &RoomId) -> Result<Option<Vec<OwnedServerName>>> {
|
fn servers_invite_via(&self, room_id: &RoomId) -> Result<Option<Vec<OwnedServerName>>> {
|
||||||
let mut key = room_id.as_bytes().to_vec();
|
let key = room_id.as_bytes().to_vec();
|
||||||
key.push(0xFF);
|
|
||||||
|
|
||||||
self.roomid_inviteviaservers
|
self.roomid_inviteviaservers
|
||||||
.get(&key)?
|
.get(&key)?
|
||||||
|
|
|
@ -217,6 +217,22 @@ impl Service {
|
||||||
self.db.appservice_in_room(room_id, appservice)
|
self.db.appservice_in_room(room_id, appservice)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Direct DB function to directly mark a user as left. It is not
|
||||||
|
/// recommended to use this directly. You most likely should use
|
||||||
|
/// `update_membership` instead
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn mark_as_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> {
|
||||||
|
self.db.mark_as_left(user_id, room_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Direct DB function to directly mark a user as joined. It is not
|
||||||
|
/// recommended to use this directly. You most likely should use
|
||||||
|
/// `update_membership` instead
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn mark_as_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> {
|
||||||
|
self.db.mark_as_joined(user_id, room_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Makes a user forget a room.
|
/// Makes a user forget a room.
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn forget(&self, room_id: &RoomId, user_id: &UserId) -> Result<()> { self.db.forget(room_id, user_id) }
|
pub fn forget(&self, room_id: &RoomId, user_id: &UserId) -> Result<()> { self.db.forget(room_id, user_id) }
|
||||||
|
|
Loading…
Add table
Reference in a new issue