Skip to content

Commit

Permalink
fix: remove client if it was connected on ws_open
Browse files Browse the repository at this point in the history
  • Loading branch information
ilbertt committed Dec 4, 2023
1 parent fe627fb commit 4ff0311
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
11 changes: 11 additions & 0 deletions src/ic-websocket-cdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ pub fn ws_open(args: CanisterWsOpenArguments) -> CanisterWsOpenResult {
.to_string_result()
})?;

// check if there's a client already registered with the same principal
// and remove it if there is
match get_client_key_from_principal(&client_key.client_principal) {
Err(_) => {
// Do nothing
},
Ok(old_client_key) => {
remove_client(&old_client_key);
},
};

// initialize client maps
let new_client = RegisteredClient::new(args.gateway_principal);
add_client(client_key.clone(), new_client);
Expand Down
19 changes: 12 additions & 7 deletions src/ic-websocket-cdk/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ pub(crate) fn add_client(client_key: ClientKey, new_client: RegisteredClient) {
increment_gateway_clients_count(new_client.gateway_principal);
}

/// Removes a client from the internal state
/// and call the on_close callback,
/// if the client was registered in the state.
pub(crate) fn remove_client(client_key: &ClientKey) {
CLIENTS_WAITING_FOR_KEEP_ALIVE.with(|set| {
set.borrow_mut().remove(client_key);
Expand All @@ -277,14 +280,16 @@ pub(crate) fn remove_client(client_key: &ClientKey) {
map.borrow_mut().remove(client_key);
});

let registered_client =
REGISTERED_CLIENTS.with(|map| map.borrow_mut().remove(client_key).unwrap());
decrement_gateway_clients_count(&registered_client.gateway_principal);
if let Some(registered_client) =
REGISTERED_CLIENTS.with(|map| map.borrow_mut().remove(client_key))
{
decrement_gateway_clients_count(&registered_client.gateway_principal);

let handlers = get_handlers_from_params();
handlers.call_on_close(OnCloseCallbackArgs {
client_principal: client_key.client_principal,
});
let handlers = get_handlers_from_params();
handlers.call_on_close(OnCloseCallbackArgs {
client_principal: client_key.client_principal,
});
};
}

pub(crate) fn format_message_for_gateway_key(
Expand Down
8 changes: 8 additions & 0 deletions src/ic-websocket-cdk/src/tests/unit_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,14 @@ proptest! {
REGISTERED_GATEWAYS.with(|map| map.borrow_mut().clear());
}

#[test]
fn test_remove_client_nonexistent(test_client_key in any::<u8>().prop_map(|_| common::get_random_client_key())) {
let res = panic::catch_unwind(|| {
remove_client(&test_client_key);
});
prop_assert!(res.is_ok());
}

#[test]
fn test_remove_client(test_client_key in any::<u8>().prop_map(|_| common::get_random_client_key())) {
// Set up
Expand Down

0 comments on commit 4ff0311

Please sign in to comment.