@@ -40,13 +40,10 @@ pub async fn process_command(
4040 let command: ChatCommand = serde_json:: from_str ( & line) ?;
4141 match command {
4242 ChatCommand :: Join ( username) => {
43- let mut users = room_state . user_set . lock ( ) . await ;
44- let user_already_exist = users . contains ( & username) ;
43+ let user_already_exist =
44+ room_state . task_handles . lock ( ) . await . contains_key ( & username) ;
4545
4646 let chat_response = if !user_already_exist {
47- users. insert ( username. clone ( ) ) ;
48- info ! ( "Users in room after addition: {:?}" , users) ;
49- info ! ( "Client {} joined as {}" , addr, username) ;
5047 let rx = room_state. tx . subscribe ( ) ;
5148 let send_task_handle = tokio:: spawn ( send_from_broadcast_channel_task (
5249 writer. clone ( ) ,
@@ -58,6 +55,11 @@ pub async fn process_command(
5855 . lock ( )
5956 . await
6057 . insert ( username. clone ( ) , send_task_handle) ;
58+ info ! (
59+ "Users in room after addition: {:?}" ,
60+ room_state. task_handles. lock( ) . await . keys( )
61+ ) ;
62+ info ! ( "Client {} joined as {}" , addr, username) ;
6163 send_to_broadcast_channel (
6264 ChatResponse :: Broadcast ( ChatMemo {
6365 username : username. clone ( ) ,
@@ -96,10 +98,7 @@ pub async fn process_command(
9698 ChatCommand :: Leave ( username) => {
9799 remove_username ( username. clone ( ) , room_state. clone ( ) ) . await ;
98100 debug ! ( "User {} has left" , username) ;
99- if let Some ( handle) = room_state. task_handles . lock ( ) . await . remove ( & username) {
100- info ! ( "Aborting background task for user: {}" , username) ;
101- handle. abort ( ) ;
102- }
101+
103102 debug ! ( "User {} has left so sending broadcast message" , username) ;
104103 send_to_broadcast_channel (
105104 ChatResponse :: Broadcast ( ChatMemo {
@@ -117,40 +116,45 @@ pub async fn process_command(
117116}
118117
119118pub async fn remove_username ( username : String , room_state : Arc < RoomState > ) {
120- let mut users = room_state. user_set . lock ( ) . await ;
121- users. remove ( & username) ;
119+ let mut lookup = room_state. task_handles . lock ( ) . await ;
120+ if let Some ( handle) = lookup. remove ( & username) {
121+ info ! ( "Aborting background task for user: {}" , username) ;
122+ handle. abort ( ) ;
123+ }
122124 info ! ( "User {} removed from room" , username) ;
123125 // list connected users
124- let users: Vec < String > = users . iter ( ) . cloned ( ) . collect ( ) ;
126+ let users: Vec < String > = lookup . keys ( ) . cloned ( ) . collect ( ) ;
125127 info ! ( "Users in room after removal: {:?}" , users) ;
126128}
127129
128130#[ cfg( test) ]
129131mod tests {
130132 use super :: * ;
131- use std:: collections:: { HashMap , HashSet } ;
133+ use std:: collections:: HashMap ;
132134 use tokio:: sync:: broadcast;
135+ use tokio:: task:: JoinHandle ;
133136
134137 #[ tokio:: test]
135138 async fn test_remove_username ( ) {
136- let mut user_set = HashSet :: new ( ) ;
137- user_set. insert ( "test_user" . to_string ( ) ) ;
138- user_set. insert ( "other_user" . to_string ( ) ) ;
139+ let mut lookup_initial = HashMap :: new ( ) ;
140+ let dummy_task: JoinHandle < Result < ( ) , RoomError > > = tokio:: spawn ( async { Ok ( ( ) ) } ) ;
141+ lookup_initial. insert ( "test_user" . to_string ( ) , dummy_task) ;
142+ let dummy_task2: JoinHandle < Result < ( ) , RoomError > > = tokio:: spawn ( async { Ok ( ( ) ) } ) ;
143+ lookup_initial. insert ( "other_user" . to_string ( ) , dummy_task2) ;
139144
140145 let ( tx, _) = broadcast:: channel ( 100 ) ;
141146 let room_state = Arc :: new ( RoomState {
142- user_set : Mutex :: new ( user_set) ,
143147 tx,
144- task_handles : Mutex :: new ( HashMap :: new ( ) ) ,
148+ task_handles : Mutex :: new ( lookup_initial ) ,
145149 } ) ;
146150
147151 // Execute removal
148152 remove_username ( "test_user" . to_string ( ) , room_state. clone ( ) ) . await ;
149153
150154 // Verify user was removed
151- let users = room_state. user_set . lock ( ) . await ;
152- assert ! ( !users . contains ( "test_user" ) ) ;
153- assert ! ( users . contains ( "other_user" ) ) ;
154- assert_eq ! ( users . len( ) , 1 ) ;
155+ let lookup = room_state. task_handles . lock ( ) . await ;
156+ assert ! ( !lookup . contains_key ( "test_user" ) ) ;
157+ assert ! ( lookup . contains_key ( "other_user" ) ) ;
158+ assert_eq ! ( lookup . len( ) , 1 ) ;
155159 }
156160}
0 commit comments