WIP - Start work on reconnect logic
This commit is contained in:
@@ -653,4 +653,69 @@ mod tests {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_channel_reconnect(mut cx: TestAppContext) {
|
||||
let user_id = 5;
|
||||
let mut client = Client::new();
|
||||
let server = FakeServer::for_client(user_id, &mut client, &cx).await;
|
||||
|
||||
let user_store = Arc::new(UserStore::new(client.clone()));
|
||||
|
||||
let channel = cx.add_model(|cx| {
|
||||
Channel::new(
|
||||
ChannelDetails {
|
||||
id: 1,
|
||||
name: "general".into(),
|
||||
},
|
||||
user_store,
|
||||
client.clone(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let join_channel = server.receive::<proto::JoinChannel>().await.unwrap();
|
||||
server
|
||||
.respond(
|
||||
join_channel.receipt(),
|
||||
proto::JoinChannelResponse {
|
||||
messages: vec![
|
||||
proto::ChannelMessage {
|
||||
id: 10,
|
||||
body: "a".into(),
|
||||
timestamp: 1000,
|
||||
sender_id: 5,
|
||||
},
|
||||
proto::ChannelMessage {
|
||||
id: 11,
|
||||
body: "b".into(),
|
||||
timestamp: 1001,
|
||||
sender_id: 5,
|
||||
},
|
||||
],
|
||||
done: false,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
let get_users = server.receive::<proto::GetUsers>().await.unwrap();
|
||||
assert_eq!(get_users.payload.user_ids, vec![5]);
|
||||
server
|
||||
.respond(
|
||||
get_users.receipt(),
|
||||
proto::GetUsersResponse {
|
||||
users: vec![proto::User {
|
||||
id: 5,
|
||||
github_login: "nathansobo".into(),
|
||||
avatar_url: "http://avatar.com/nathansobo".into(),
|
||||
}],
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
// Disconnect, wait for the client to reconnect.
|
||||
server.disconnect().await;
|
||||
cx.foreground().advance_clock(Duration::from_secs(10));
|
||||
let get_messages = server.receive::<proto::GetChannelMessages>().await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -146,14 +146,27 @@ impl Client {
|
||||
}));
|
||||
}
|
||||
Status::ConnectionLost => {
|
||||
state._maintain_connection = Some(cx.foreground().spawn(async move {
|
||||
// TODO: try to reconnect
|
||||
let this = self.clone();
|
||||
let foreground = cx.foreground();
|
||||
state._maintain_connection = Some(cx.spawn(|cx| async move {
|
||||
let mut delay_seconds = 5;
|
||||
while let Err(error) = this.authenticate_and_connect(&cx).await {
|
||||
log::error!("failed to connect {}", error);
|
||||
let delay = Duration::from_secs(delay_seconds);
|
||||
this.set_status(
|
||||
Status::ReconnectionError {
|
||||
next_reconnection: Instant::now() + delay,
|
||||
},
|
||||
&cx,
|
||||
);
|
||||
foreground.sleep(delay).await;
|
||||
delay_seconds = (delay_seconds * 2).min(300);
|
||||
}
|
||||
}));
|
||||
}
|
||||
Status::Disconnected => {
|
||||
_ => {
|
||||
state._maintain_connection.take();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user