2 votes

Pourquoi hyper exige-t-il que le Handler implémente Sync au lieu d'utiliser des Handlers indépendants par thread ?

Hyper présente les caractéristiques suivantes exemple d'un Handler qui met en œuvre Sync :

use std::sync::Mutex;
use std::sync::mpsc::{channel, Sender};
use hyper::server::{Handler, Server, Request, Response};

struct SenderHandler {
    sender: Mutex<Sender<&'static str>>
}

impl Handler for SenderHandler {
    fn handle(&self, req: Request, res: Response) {
        self.sender.lock().unwrap().send("start").unwrap();
    }
}

et précise qu'un Handler doit mettre en œuvre Sync puisque Handler peuvent être appelées à partir de plusieurs fils d'exécution.

Pour moi, cela ressemble à une pénalité de performance inutile. Ce que je préférerais, c'est mettre en place un SenderHandler par thread, chacun étant indépendant, ce qui supprimerait l'obligation d'implémenter un système de gestion de l'information. Sync .

Ai-je mal compris Hyper, le système de type de Rust ou est-ce impossible ?

4voto

Matthieu M. Points 101624

Il s'agit d'une question de papercut.

Sync est implémenté de manière triviale pour tout gestionnaire sans état ; le fait de disposer d'une fonction Clone Le fait d'être lié au lieu de cela signifierait avoir plusieurs états concurrents évoluant indépendamment les uns des autres (avec des demandes distribuées de manière aléatoire). Je ne suis même pas sûr qu'il y ait une garantie que pendant que attente pendant le traitement d'une demande, le même thread est appelé avec le résultat.

En utilisant Sync L'auteur vous oblige à réfléchir à ce que signifie le partage d'un état entre des requêtes (ou même à l'intérieur d'une même requête).


Comme dans l'exemple fourni, j'aimerais supprimer le Mutex protégeant l'expéditeur, car l'expéditeur est déjà conçu pour le passage de messages intrathread sans verrou. Tout ce dont il a besoin, c'est d'un clone par thread.

Vous pouvez avoir Sender mettre en œuvre Sync si c'est le cas (réfléchissez bien, évidemment), puis supprimez le Mutex .

Il est également possible, bien que ce ne soit pas très élégant, d'avoir une instance par thread en utilisant la fonction thread_local! puis un gestionnaire de trampolines distribue le travail à la macro thread-local Sender lors de l'invocation.


Enfin, notez que l'hyper est actuellement en cours de refonte ; il devrait être déplacé vers Future ce qui peut ou non entraîner un réexamen de la situation.

3voto

PureW Points 691

D'accord, cela semble en fait impossible pour le moment dans Hyper. Il en est question dans numéro 248 et le développeur préfère Sync plus Clone :

Nous en avons parlé sur IRC. Synoptique simple Clone Les utilisateurs pourraient facilement avoir un état sur leur main. est modifié à chaque demande, mais au lieu de cela, il aurait été cloné. plusieurs fois et ne modifierait pas ce qu'ils espéraient. Au lieu de cela, il vaut mieux de forcer l'utilisateur à s'assurer que son état est synchronisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X