Browse Source

Fix deadlock when on_click is called

new_protocol
ThePerkinrex 5 years ago
parent
commit
44a1761c05
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 82
      server/src/server/game.rs
  2. 4
      unity/Assets/Scripts/Client.cs

82
server/src/server/game.rs

@ -49,7 +49,7 @@ impl GameService {
None => return Err(Status::failed_precondition("User isn't in a lobby")),
};
let games_lock = self.running_games.read().await; // This encounters a deadlock
// log::info!("Locked games");
// log::info!("Locked games");
let game_lock = match games_lock.get(&lobby) {
Some(x) => x.read().await,
None => {
@ -149,7 +149,6 @@ impl GameService {
}
async fn get_default_status(&self, uuid: uuid::Uuid) -> Result<Option<MessageStatus>, Status> {
log::info!("Getting the deafult status for {}", uuid);
let lobby = {
let mut conn = self.conn.write().await;
@ -159,8 +158,7 @@ impl GameService {
};
lobby
};
let r =
Ok(self
let r = Ok(self
.running_games
.read()
.await
@ -173,7 +171,7 @@ impl GameService {
.2
.get()
.clone());
log::info!("Gotten the deafult status for {}", uuid);
log::info!("Gotten the deafult status for {}", uuid);
r
}
}
@ -214,7 +212,6 @@ impl game_server::Game for GameService {
// log::info!("Loading back image [{:?}]", time.elapsed());
let back_buf = tokio::fs::read(back).await.unwrap();
log::info!("Loaded images [{:?}]", time.elapsed());
Ok(Response::new(Image {
face: face_buf,
@ -228,39 +225,44 @@ impl game_server::Game for GameService {
) -> Result<tonic::Response<()>, Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x {
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?;
let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")),
};
let games_lock = self.running_games.read().await;
let mut game_lock = match games_lock.get(&lobby) {
Some(x) => x.write().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
client_id::Error::MalformedUuid => {
Status::failed_precondition("malformed client_id")
}
};
let game = &mut game_lock.1;
let card = request.into_inner();
let idx = match card.card_index.unwrap().pos.unwrap() {
super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom,
super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top,
super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize),
};
let pile_kind = match card.pile_kind.unwrap().kind.unwrap() {
super::grpc::game::pile_kind::Kind::Common(()) => PileKind::Common,
super::grpc::game::pile_kind::Kind::Owned(p) => PileKind::Owned(p),
};
let card: CardId = CardId {
idx,
pile_kind,
pile_name: card.pile_name,
};
game.on_click(card, game.get_player_for_uuid(&uuid).unwrap());
})?;
{
let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")),
};
log::debug!("{} clicked a card in the lobby {}", uuid, lobby);
let games_lock = self.running_games.read().await;
let mut game_lock = match games_lock.get(&lobby) {
Some(x) => x.write().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &mut game_lock.1;
let card = request.into_inner();
let idx = match card.card_index.unwrap().pos.unwrap() {
super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom,
super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top,
super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize),
};
let pile_kind = match card.pile_kind.unwrap().kind.unwrap() {
super::grpc::game::pile_kind::Kind::Common(()) => PileKind::Common,
super::grpc::game::pile_kind::Kind::Owned(p) => PileKind::Owned(p),
};
let card: CardId = CardId {
idx,
pile_kind,
pile_name: card.pile_name,
};
game.on_click(card, game.get_player_for_uuid(&uuid).unwrap());
} // drop the connection so that the lock is released
self.update_status(uuid).await?;
Ok(Response::new(()))
}
@ -282,9 +284,7 @@ impl game_server::Game for GameService {
r
});
log::info!("Status is acquired");
let r= Ok(Response::new(
status,
));
let r = Ok(Response::new(status));
log::info!("Given game status to {}", uuid);
r
}

4
unity/Assets/Scripts/Client.cs

@ -210,12 +210,12 @@ public static class Client
public int GetUserIndex(string user) {
var status = game_client.status(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) });
return status.Names.IndexOf(new Common.Name() { Name_ = user });
return status.Names.IndexOf(new Common.Name { Name_ = user });
}
public Dictionary<string, Dictionary<string, Game.MessageStatus.Types.Pile>> OnClickCard(string pileName, bool isCommonPile, int cardIdx, string user) {
Game.PileKind pileKind = new Game.PileKind() { Owned = (uint)GetUserIndex(user) };
game_client.onClick(new Game.CardId() { PileKind = pileKind, CardIndex = new Game.CardIndex() { Index = (uint)cardIdx }, PileName = pileName }, new Metadata { new Metadata.Entry("client_id", connId) });
game_client.onClick(new Game.CardId { PileKind = pileKind, CardIndex = new Game.CardIndex { Index = (uint)cardIdx }, PileName = pileName }, new Metadata { new Metadata.Entry("client_id", connId) });
return GetPiles(user);
}

Loading…
Cancel
Save