@@ -40,13 +40,10 @@ pub async fn process_command(
40
40
let command: ChatCommand = serde_json:: from_str ( & line) ?;
41
41
match command {
42
42
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) ;
45
45
46
46
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) ;
50
47
let rx = room_state. tx . subscribe ( ) ;
51
48
let send_task_handle = tokio:: spawn ( send_from_broadcast_channel_task (
52
49
writer. clone ( ) ,
@@ -58,6 +55,11 @@ pub async fn process_command(
58
55
. lock ( )
59
56
. await
60
57
. 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) ;
61
63
send_to_broadcast_channel (
62
64
ChatResponse :: Broadcast ( ChatMemo {
63
65
username : username. clone ( ) ,
@@ -96,10 +98,7 @@ pub async fn process_command(
96
98
ChatCommand :: Leave ( username) => {
97
99
remove_username ( username. clone ( ) , room_state. clone ( ) ) . await ;
98
100
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
+
103
102
debug ! ( "User {} has left so sending broadcast message" , username) ;
104
103
send_to_broadcast_channel (
105
104
ChatResponse :: Broadcast ( ChatMemo {
@@ -117,40 +116,45 @@ pub async fn process_command(
117
116
}
118
117
119
118
pub 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
+ }
122
124
info ! ( "User {} removed from room" , username) ;
123
125
// list connected users
124
- let users: Vec < String > = users . iter ( ) . cloned ( ) . collect ( ) ;
126
+ let users: Vec < String > = lookup . keys ( ) . cloned ( ) . collect ( ) ;
125
127
info ! ( "Users in room after removal: {:?}" , users) ;
126
128
}
127
129
128
130
#[ cfg( test) ]
129
131
mod tests {
130
132
use super :: * ;
131
- use std:: collections:: { HashMap , HashSet } ;
133
+ use std:: collections:: HashMap ;
132
134
use tokio:: sync:: broadcast;
135
+ use tokio:: task:: JoinHandle ;
133
136
134
137
#[ tokio:: test]
135
138
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) ;
139
144
140
145
let ( tx, _) = broadcast:: channel ( 100 ) ;
141
146
let room_state = Arc :: new ( RoomState {
142
- user_set : Mutex :: new ( user_set) ,
143
147
tx,
144
- task_handles : Mutex :: new ( HashMap :: new ( ) ) ,
148
+ task_handles : Mutex :: new ( lookup_initial ) ,
145
149
} ) ;
146
150
147
151
// Execute removal
148
152
remove_username ( "test_user" . to_string ( ) , room_state. clone ( ) ) . await ;
149
153
150
154
// 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 ) ;
155
159
}
156
160
}
0 commit comments