Skip to content

Draft: PR bidon pour faire une review du repo#1

Open
desbma wants to merge 26 commits intoreviewfrom
main
Open

Draft: PR bidon pour faire une review du repo#1
desbma wants to merge 26 commits intoreviewfrom
main

Conversation

@desbma
Copy link
Copy Markdown
Collaborator

@desbma desbma commented Nov 1, 2024

No description provided.

Copy link
Copy Markdown
Collaborator Author

@desbma desbma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est pas mal du tout ton petit projet !

J'ai fait un pull request bidon à partir du premier commit juste pour avoir l'interface de review.

Pour le choix des crates, tu as pris des libs connues et matures, j'aurai pas fait des choix différents je pense.

Il y a quelques trucs pas idiomatiques, mais franchement mineurs.

Le plus gros changement que je ferai c'est de convertir en async, car on "sent" que le code a été converti à partir de C/C++.

En passant en async, je pense que tu pourrais diviser la taille de ton code par deux, car il serait plus haut niveau. Par contre ça te fait rentrer dans un autre monde, tu serai obligé de réécrire tout ce qui fait des threads (si tu en as encore besoin) ou entrées/sorties en async, de remplacer certaines dépendances, etc.

En même temps, il n'y a pas énormément de code, donc si t'es motivé, ça peut te faire un exercice fun et pas trop chronophage 😉

src/server.rs Outdated
Comment on lines +10 to +16
loop {
let (socket, addr) = listener.accept().unwrap();
match Client::create(socket) {
Err(e) => log::warn!("Impossible de connecter le nouveau client {} : {}", addr, e),
Ok(()) => log::info!("Nouveau client connecte : {}", addr)
}
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mineur : Tu peux simplifier en chaînant les méthodes des itérateurs :

Suggested change
loop {
let (socket, addr) = listener.accept().unwrap();
match Client::create(socket) {
Err(e) => log::warn!("Impossible de connecter le nouveau client {} : {}", addr, e),
Ok(()) => log::info!("Nouveau client connecte : {}", addr)
}
}
listener.incoming().map(Result::unwrap).for_each(|socket| {
let addr = socket.peer_addr().unwrap();
match Client::create(socket) {
Err(e) => log::warn!("Impossible de connecter le nouveau client {} : {}", addr, e),
Ok(()) => log::info!("Nouveau client connecte : {}", addr),
}
});

Ou encore plus en déplaçant le logging dans Client::create :

Suggested change
loop {
let (socket, addr) = listener.accept().unwrap();
match Client::create(socket) {
Err(e) => log::warn!("Impossible de connecter le nouveau client {} : {}", addr, e),
Ok(()) => log::info!("Nouveau client connecte : {}", addr)
}
}
listener.incoming().map(Result::unwrap).for_each(Client::create);

Comment on lines +77 to +81
// Serialisation de l'info de trafic dans un buffer pour pouvoir l'envoyer
let buf = bincode::serialize(traffic_infos).unwrap();

// Envoi du buffer sur la socket multicast
self.socket.send(&buf).unwrap();
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comme Socket implémente le trait Write, tu peux faire directement :

Suggested change
// Serialisation de l'info de trafic dans un buffer pour pouvoir l'envoyer
let buf = bincode::serialize(traffic_infos).unwrap();
// Envoi du buffer sur la socket multicast
self.socket.send(&buf).unwrap();
bincode::serialize_into(self.socket).unwrap();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai l'impression que std::net::UdpSocket n'implemente pas le trait Write alors que std::net::TcpStream l'implémente. Je ne saurai pas te dire pourquoi.


/// Recoit un datagram
/// Attention : en cas d'erreur, il faut faire appel a clear pour recevoir un nouveau datagram
pub fn recv(&mut self, mut sock: &TcpStream) -> anyhow::Result<Option<&[u8]>> {
Copy link
Copy Markdown
Collaborator Author

@desbma desbma Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce code et Client::work_thread me laisse penser que ton programme bénéficierai fortement à être réécrit en async.

Tu pourrais faire la lecture de la taille, puis la lecture du buffer, dans les deux cas avec read_exact, et retourner que quand tu as un message complet ou une erreur, sans gérer d'état interne intermédiaire, ce qui simplifierai beaucoup la logique. Le runtime ferait le changement de contexte entre les sockets, et l'équivalent du poll, et ton code serait plus haut niveau.
A noter que c'est possible d'être async et mono thread avec tokio, cf. https://docs.rs/tokio/latest/tokio/runtime/index.html#current-thread-scheduler

@desbma desbma changed the title WIP: PR bidon pour faire une review du repo Draft: PR bidon pour faire une review du repo Nov 1, 2024
// Envoi de l'info de trafic aux clients
self.sender.send(&traffic_infos);
}
match reader.read_event()? {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pour parser du XML avec quick-xml, tu peux utiliser l'API event comme tu as fait (qui déboite pour la perf, car 0-copy), mais tu peux aussi définir une struct pour représenter le document XML, ajouter derive(serde::Deserialize) dessus, implémenter FromStr pour TrafficInfos, et serde fera tout le reste. La deuxième approche est beaucoup plus simple je trouve.
Exemple au hasard : https://github.com/desbma/stfed/blob/master/src/config.rs#L45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants