fix: send presence too often
This commit is contained in:
		
							parent
							
								
									32da76b9a2
								
							
						
					
					
						commit
						d404f902bf
					
				
					 4 changed files with 36 additions and 74 deletions
				
			
		|  | @ -548,9 +548,8 @@ pub fn set_displayname_route( | |||
| 
 | ||||
|     // Presence update
 | ||||
|     db.global_edus | ||||
|         .update_globallatest( | ||||
|             &user_id, | ||||
|             EduEvent::Presence(ruma_events::presence::PresenceEvent { | ||||
|         .update_presence( | ||||
|             ruma_events::presence::PresenceEvent { | ||||
|                 content: ruma_events::presence::PresenceEventContent { | ||||
|                     avatar_url: db.users.avatar_url(&user_id).unwrap(), | ||||
|                     currently_active: None, | ||||
|  | @ -560,7 +559,7 @@ pub fn set_displayname_route( | |||
|                     status_msg: None, | ||||
|                 }, | ||||
|                 sender: user_id.clone(), | ||||
|             }), | ||||
|             }, | ||||
|             &db.globals, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|  | @ -640,9 +639,8 @@ pub fn set_avatar_url_route( | |||
| 
 | ||||
|     // Presence update
 | ||||
|     db.global_edus | ||||
|         .update_globallatest( | ||||
|             &user_id, | ||||
|             EduEvent::Presence(ruma_events::presence::PresenceEvent { | ||||
|         .update_presence( | ||||
|             ruma_events::presence::PresenceEvent { | ||||
|                 content: ruma_events::presence::PresenceEventContent { | ||||
|                     avatar_url: db.users.avatar_url(&user_id).unwrap(), | ||||
|                     currently_active: None, | ||||
|  | @ -652,7 +650,7 @@ pub fn set_avatar_url_route( | |||
|                     status_msg: None, | ||||
|                 }, | ||||
|                 sender: user_id.clone(), | ||||
|             }), | ||||
|             }, | ||||
|             &db.globals, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|  | @ -707,9 +705,8 @@ pub fn set_presence_route( | |||
|     let user_id = body.user_id.as_ref().expect("user is authenticated"); | ||||
| 
 | ||||
|     db.global_edus | ||||
|         .update_globallatest( | ||||
|             &user_id, | ||||
|             EduEvent::Presence(ruma_events::presence::PresenceEvent { | ||||
|         .update_presence( | ||||
|             ruma_events::presence::PresenceEvent { | ||||
|                 content: ruma_events::presence::PresenceEventContent { | ||||
|                     avatar_url: db.users.avatar_url(&user_id).unwrap(), | ||||
|                     currently_active: None, | ||||
|  | @ -719,7 +716,7 @@ pub fn set_presence_route( | |||
|                     status_msg: body.status_msg.clone(), | ||||
|                 }, | ||||
|                 sender: user_id.clone(), | ||||
|             }), | ||||
|             }, | ||||
|             &db.globals, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|  | @ -2435,24 +2432,16 @@ pub fn sync_route( | |||
|         presence: sync_events::Presence { | ||||
|             events: db | ||||
|                 .global_edus | ||||
|                 .globallatests_since(since) | ||||
|                 .presence_since(since) | ||||
|                 .unwrap() | ||||
|                 .filter_map(|edu| { | ||||
|                     // Only look for presence events
 | ||||
|                     if let Ok(mut edu) = EventJson::<ruma_events::presence::PresenceEvent>::from( | ||||
|                         edu.unwrap().into_json(), | ||||
|                     ) | ||||
|                     .deserialize() | ||||
|                     { | ||||
|                         let timestamp = edu.content.last_active_ago.unwrap(); | ||||
|                         edu.content.last_active_ago = Some( | ||||
|                             js_int::UInt::try_from(utils::millis_since_unix_epoch()).unwrap() | ||||
|                                 - timestamp, | ||||
|                         ); | ||||
|                         Some(edu.into()) | ||||
|                     } else { | ||||
|                         None | ||||
|                     } | ||||
|                 .map(|edu| { | ||||
|                     let mut edu = edu.unwrap().deserialize().unwrap(); | ||||
|                     let timestamp = edu.content.last_active_ago.unwrap(); | ||||
|                     let last_active_ago = js_int::UInt::try_from(utils::millis_since_unix_epoch()) | ||||
|                         .unwrap() | ||||
|                         - timestamp; | ||||
|                     edu.content.last_active_ago = Some(last_active_ago); | ||||
|                     edu.into() | ||||
|                 }) | ||||
|                 .collect(), | ||||
|         }, | ||||
|  |  | |||
|  | @ -94,8 +94,7 @@ impl Database { | |||
|                 roomuserdataid_accountdata: db.open_tree("roomuserdataid_accountdata").unwrap(), | ||||
|             }, | ||||
|             global_edus: global_edus::GlobalEdus { | ||||
|                 //globalallid_globalall: db.open_tree("globalallid_globalall").unwrap(),
 | ||||
|                 globallatestid_globallatest: db.open_tree("globallatestid_globallatest").unwrap(), // Presence
 | ||||
|                 presenceid_presence: db.open_tree("presenceid_presence").unwrap(), // Presence
 | ||||
|             }, | ||||
|             media: media::Media { | ||||
|                 mediaid_file: db.open_tree("mediaid_file").unwrap(), | ||||
|  |  | |||
|  | @ -1,67 +1,53 @@ | |||
| use crate::Result; | ||||
| use ruma_events::{collections::only::Event as EduEvent, EventJson}; | ||||
| use ruma_identifiers::UserId; | ||||
| use ruma_events::EventJson; | ||||
| 
 | ||||
| pub struct GlobalEdus { | ||||
|     //pub globalallid_globalall: sled::Tree, // ToDevice, GlobalAllId = UserId + Count
 | ||||
|     pub(super) globallatestid_globallatest: sled::Tree, // Presence, GlobalLatestId = Count + UserId
 | ||||
|     pub(super) presenceid_presence: sled::Tree, // Presence, PresenceId = Count + UserId
 | ||||
| } | ||||
| 
 | ||||
| impl GlobalEdus { | ||||
|     /// Adds a global event which will be saved until a new event replaces it (e.g. presence updates).
 | ||||
|     pub fn update_globallatest( | ||||
|     pub fn update_presence( | ||||
|         &self, | ||||
|         user_id: &UserId, | ||||
|         event: EduEvent, | ||||
|         presence: ruma_events::presence::PresenceEvent, | ||||
|         globals: &super::globals::Globals, | ||||
|     ) -> Result<()> { | ||||
|         // Remove old entry
 | ||||
|         if let Some(old) = self | ||||
|             .globallatestid_globallatest | ||||
|             .presenceid_presence | ||||
|             .iter() | ||||
|             .keys() | ||||
|             .rev() | ||||
|             .filter_map(|r| r.ok()) | ||||
|             .find(|key| { | ||||
|                 key.rsplit(|&b| b == 0xff).next().unwrap() == user_id.to_string().as_bytes() | ||||
|                 key.rsplit(|&b| b == 0xff).next().unwrap() == presence.sender.to_string().as_bytes() | ||||
|             }) | ||||
|         { | ||||
|             // This is the old global_latest
 | ||||
|             self.globallatestid_globallatest.remove(old)?; | ||||
|             self.presenceid_presence.remove(old)?; | ||||
|         } | ||||
| 
 | ||||
|         let mut global_latest_id = globals.next_count()?.to_be_bytes().to_vec(); | ||||
|         global_latest_id.push(0xff); | ||||
|         global_latest_id.extend_from_slice(&user_id.to_string().as_bytes()); | ||||
|         let mut presence_id = globals.next_count()?.to_be_bytes().to_vec(); | ||||
|         presence_id.push(0xff); | ||||
|         presence_id.extend_from_slice(&presence.sender.to_string().as_bytes()); | ||||
| 
 | ||||
|         self.globallatestid_globallatest | ||||
|             .insert(global_latest_id, &*serde_json::to_string(&event)?)?; | ||||
|         self.presenceid_presence | ||||
|             .insert(presence_id, &*serde_json::to_string(&presence)?)?; | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns an iterator over the most recent presence updates that happened after the event with id `since`.
 | ||||
|     pub fn globallatests_since( | ||||
|     pub fn presence_since( | ||||
|         &self, | ||||
|         since: u64, | ||||
|     ) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> { | ||||
|         let first_possible_edu = since.to_be_bytes().to_vec(); | ||||
|     ) -> Result<impl Iterator<Item = Result<EventJson<ruma_events::presence::PresenceEvent>>>> { | ||||
|         let first_possible_edu = (since + 1).to_be_bytes().to_vec(); // +1 so we don't send the event at since
 | ||||
| 
 | ||||
|         Ok(self | ||||
|             .globallatestid_globallatest | ||||
|             .presenceid_presence | ||||
|             .range(&*first_possible_edu..) | ||||
|             // Skip the first pdu if it's exactly at since, because we sent that last time
 | ||||
|             .skip( | ||||
|                 if self | ||||
|                     .globallatestid_globallatest | ||||
|                     .get(first_possible_edu)? | ||||
|                     .is_some() | ||||
|                 { | ||||
|                     1 | ||||
|                 } else { | ||||
|                     0 | ||||
|                 }, | ||||
|             ) | ||||
|             .filter_map(|r| r.ok()) | ||||
|             .map(|(_, v)| Ok(serde_json::from_slice(&v)?))) | ||||
|     } | ||||
|  |  | |||
|  | @ -59,23 +59,11 @@ impl RoomEdus { | |||
|         prefix.push(0xff); | ||||
| 
 | ||||
|         let mut first_possible_edu = prefix.clone(); | ||||
|         first_possible_edu.extend_from_slice(&since.to_be_bytes()); | ||||
|         first_possible_edu.extend_from_slice(&(since + 1).to_be_bytes()); // +1 so we don't send the event at since
 | ||||
| 
 | ||||
|         Ok(self | ||||
|             .roomlatestid_roomlatest | ||||
|             .range(&*first_possible_edu..) | ||||
|             // Skip the first pdu if it's exactly at since, because we sent that last time
 | ||||
|             .skip( | ||||
|                 if self | ||||
|                     .roomlatestid_roomlatest | ||||
|                     .get(first_possible_edu)? | ||||
|                     .is_some() | ||||
|                 { | ||||
|                     1 | ||||
|                 } else { | ||||
|                     0 | ||||
|                 }, | ||||
|             ) | ||||
|             .filter_map(|r| r.ok()) | ||||
|             .take_while(move |(k, _)| k.starts_with(&prefix)) | ||||
|             .map(|(_, v)| Ok(serde_json::from_slice(&v)?))) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue