Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3361682
D8631.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D8631.diff
View Options
diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -830,18 +830,11 @@
&message.signature,
)?;
- let mut filtered_usernames = Vec::new();
-
- for username in usernames {
- if !self
- .client
- .username_taken(username.clone())
- .await
- .map_err(handle_db_error)?
- {
- filtered_usernames.push(username);
- }
- }
+ let filtered_usernames = self
+ .client
+ .filter_out_taken_usernames(usernames)
+ .await
+ .map_err(handle_db_error)?;
self
.client
diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs
--- a/services/identity/src/database.rs
+++ b/services/identity/src/database.rs
@@ -1,5 +1,5 @@
use constant_time_eq::constant_time_eq;
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::str::FromStr;
use std::sync::Arc;
@@ -485,6 +485,23 @@
Ok(result.is_some())
}
+ pub async fn filter_out_taken_usernames(
+ &self,
+ usernames: Vec<String>,
+ ) -> Result<Vec<String>, Error> {
+ let db_usernames = self.get_all_usernames().await?;
+
+ let db_usernames_set: HashSet<String> = db_usernames.into_iter().collect();
+ let usernames_set: HashSet<String> = usernames.into_iter().collect();
+
+ let available_usernames: Vec<String> = usernames_set
+ .difference(&db_usernames_set)
+ .cloned()
+ .collect();
+
+ Ok(available_usernames)
+ }
+
async fn get_user_from_user_info(
&self,
user_info: String,
@@ -631,12 +648,12 @@
.map_err(|e| Error::AwsSdk(e.into()))
}
- pub async fn get_users(&self) -> Result<Vec<String>, Error> {
+ async fn get_all_usernames(&self) -> Result<Vec<String>, Error> {
let scan_output = self
.client
.scan()
.table_name(USERS_TABLE)
- .projection_expression(USERS_TABLE_PARTITION_KEY)
+ .projection_expression(USERS_TABLE_USERNAME_ATTRIBUTE)
.send()
.await
.map_err(|e| Error::AwsSdk(e.into()))?;
@@ -644,12 +661,12 @@
let mut result = Vec::new();
if let Some(attributes) = scan_output.items {
for mut attribute in attributes {
- let id = parse_string_attribute(
- USERS_TABLE_PARTITION_KEY,
- attribute.remove(USERS_TABLE_PARTITION_KEY),
- )
- .map_err(Error::Attribute)?;
- result.push(id);
+ if let Ok(username) = parse_string_attribute(
+ USERS_TABLE_USERNAME_ATTRIBUTE,
+ attribute.remove(USERS_TABLE_USERNAME_ATTRIBUTE),
+ ) {
+ result.push(username);
+ }
}
}
Ok(result)
@@ -683,49 +700,29 @@
&self,
usernames: Vec<String>,
) -> Result<(), Error> {
- let mut write_requests = vec![];
-
- for username in usernames {
- let item: HashMap<String, AttributeValue> = vec![(
- RESERVED_USERNAMES_TABLE_PARTITION_KEY.to_string(),
- AttributeValue::S(username),
- )]
- .into_iter()
- .collect();
-
- let write_request = WriteRequest::builder()
- .put_request(PutRequest::builder().set_item(Some(item)).build())
- .build();
-
- write_requests.push(write_request);
- }
-
- loop {
- let output = self
+ // A single call to BatchWriteItem can consist of up to 25 operations
+ for usernames_chunk in usernames.chunks(25) {
+ let write_requests = usernames_chunk
+ .iter()
+ .map(|username| {
+ let put_request = PutRequest::builder()
+ .item(
+ RESERVED_USERNAMES_TABLE_PARTITION_KEY,
+ AttributeValue::S(username.to_string()),
+ )
+ .build();
+
+ WriteRequest::builder().put_request(put_request).build()
+ })
+ .collect();
+
+ self
.client
.batch_write_item()
.request_items(RESERVED_USERNAMES_TABLE, write_requests)
.send()
.await
.map_err(|e| Error::AwsSdk(e.into()))?;
-
- let unprocessed_items_map = match output.unprocessed_items() {
- Some(map) => map,
- None => break,
- };
-
- let unprocessed_requests =
- match unprocessed_items_map.get(RESERVED_USERNAMES_TABLE) {
- Some(requests) => requests,
- None => break,
- };
-
- info!(
- "{} unprocessed items, retrying...",
- unprocessed_requests.len()
- );
-
- write_requests = unprocessed_requests.to_vec();
}
info!("Batch write item to reserved usernames table succeeded");
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 25, 6:51 PM (19 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2580712
Default Alt Text
D8631.diff (4 KB)
Attached To
Mode
D8631: [identity] fix add_reserved_usernames RPC
Attached
Detach File
Event Timeline
Log In to Comment