2009-11-29 8 views
2

J'essaie d'ajouter un nouveau transport à Twisted, qui va lire les données d'un flux - soit un fichier d'une manière tail -f, ou d'un tuyau, mais j'ai quelques problèmes avec Twisted architecture. Prêt, le transport lui-même (implémente ITransport) est prêt - il gère toutes les ouvertures de fichiers. J'ai des fonctions de streaming/différées prêtes. Comment puis-je le mettre ensemble maintenant? Je souhaite rapporter les nouvelles données à certains protocoles dataReceived().Nouveau type de transport et de lecteur dans Twisted

Je pourrais bien sûr créer un nouvel objet qui va configurer les moniteurs d'E/S avec des rappels appropriés, enregistrer un rappel à la fermeture du réacteur (pour fermer les fichiers/protocoles) et tout démarrer manuellement - mais c'est le droit chemin"? Y a-t-il une meilleure abstraction que je pourrais utiliser? J'ai vu reactor.connectWith(), mais il ne fournit pas vraiment beaucoup d'une abstraction ...

Aussi - comment suis-je censé transmettre les données de mon lecteur au protocole? ITransport ne définit aucune interface pour cela, même si cela semble être la responsabilité du transport.

Répondre

5

Il semble que vous ayez surtout compris comment faire. Vous pourriez être intéressé par twisted.internet.fdesc.readFromFD, mais il ne s'agit que de quelques lignes et il ne fait rien de particulièrement compliqué (c'est quelques lignes que vous n'avez pas à maintenir, cependant). En dehors de cela - oui, vous devez faire la surveillance des E/S dans ce cas, car les descripteurs de fichiers normaux ne sont pas supportés par select/poll/epoll (ils sont toujours déclarés prêts, pas ce que vous voulez).

Un travail a été fait sur la prise en charge de inotify dans Twisted (http://twistedmatrix.com/trac/ticket/972) mais ce n'est pas encore terminé, il ne vous sera donc pas directement utile maintenant (à moins que vous ne souhaitiez l'utiliser). En supposant que vous n'utilisez que l'interrogation basée sur le temps, une grande partie de ce qui est dans le réacteur ne vous aidera pas beaucoup, car ce code est basé sur une API de disponibilité fournie par le système (c.-à-d. .

Pour le cas de tuyau, cependant, vous devriez être en mesure d'utiliser et de bénéficier des méthodes IReactorFDSet - addReader et al. Votre transport d'interrogation basé sur le temps peut encore bénéficier de l'implémentation ITransport - bien que je ne sache pas comment implémenter write pour un transport similaire à tail -f. Vous aurez certainement avantage à ce que votre transport livre des données via l'interface IProtocol, car cela simplifie la réutilisation du code. IProtocol.dataReceived est exactement comment vous voulez passer les données de votre lecteur (Je pense que c'est la même chose que votre transport, n'est-ce pas?). Ceci n'est pas défini sur ITransport car c'est une méthode que vous appelez sur un autre objet qui n'est pas le transport.

reactor.connectWith probablement ne va pas vous acheter quelque chose. Comme vous le dites, ce n'est pas vraiment une abstraction; Je dirais que c'est plus une erreur. :)

Ne vous inquiétez pas trop de ne pas pouvoir ajouter des méthodes directement au réacteur. Une fonction libre qui accepte un réacteur comme paramètre est tout aussi simple à utiliser.

Pour le rappel d'arrêt, addReader devrait vous permettre d'y accéder en grande partie. Tout lecteur dans le réacteur au moment de l'arrêt aura connectionLost appelé (partie de IFileDescriptor). Vous devez implémenter ceci pour nettoyer les fichiers et le protocole.