2015-10-14 1 views
0

J'ai un serveur Linux qui traite les requêtes Cap'n Proto RPC. Certaines de ces demandes doivent transmettre des données dans la requête à un autre serveur exécutant, dans ce cas, un courtier Kafka. Les bibliothèques librdkafka et Cap'n Proto KJ peuvent toutes deux utiliser poll(), donc je pense que le système d'exploitation s'assurera qu'elles peuvent fonctionner de manière asynchrone, mais je ne suis pas sûr qu'une intégration plus poussée soit nécessaire ou bénéfique. Est-ce que quelqu'un a de l'expérience avec ça?Quelle est la meilleure façon d'intégrer des API asynchrones tierces avec Cap'n Proto RPC?

La question est un peu plus large que les détails que j'ai énumérés .. il y a d'autres API que je pourrais appeler à l'avenir de Cap'n Proto RPC, donc des lignes directrices générales seraient appréciées.

Répondre

2

Malheureusement, ce n'est pas si simple. Oui, ils utilisent tous les deux poll(), mais le problème est qu'une seule bibliothèque appellera poll() à la fois, et que seule cette bibliothèque recevra des événements - l'autre est bloquée. C'est un défi classique avec les bibliothèques de boucles d'événements - par défaut, elles ne peuvent pas être utilisées ensemble.

Une option consiste à essayer d'utiliser les bibliothèques dans des threads distincts. Mais, souvent, les bibliothèques événementielles sont conçues autour de l'hypothèse que vous faites tout dans un seul thread, sinon pourquoi auriez-vous besoin d'une boucle d'événements?

Mais "The Right Thing" est d'intégrer les boucles d'événements. La boucle d'événements de KJ peut être intégrée à d'autres bibliothèques d'événements. Par exemple, je l'ai intégré avec libuv pour node-capnp; voir la première partie de ce fichier: (. À un certain moment je prévois de séparer le code lié à libuv-ici dans une bibliothèque séparée livrée avec Cap'n Proto)

https://github.com/kentonv/node-capnp/blob/master/src/node-capnp/capnp.cc

Pour un autre Par exemple, voici une requête de Nathan Hourt pour ajouter une intégration avec la boucle d'événement de Qt - mais notez que celle-ci n'inclut pas l'intégration E/S, je pense que Nathan utilise une implémentation de AsyncIoStream dans laquelle il pousse manuellement les données lorsqu'il est disponible:

https://github.com/sandstorm-io/capnproto/pull/253

Dans tous les cas, vous devrez faire quelque chose de similaire avec ce que Kafka utilise. J'espère que vous pourrez ensuite apporter votre code à Cap'n Proto! :)

+0

merci Kenton. J'ai regardé la mise en œuvre du noeud mais j'étais un peu prudent car il a ajouté libuv dans le mix et c'était considéré comme lent et un peu kludgy. Je suis tenté de déplacer les bits de Kafka dans une nouvelle lib qui est liée aux interfaces de KJ. Ce serait bien si le pipeline RPC pouvait accéder à la nouvelle fonctionnalité avec zéro copie, mais je ne suis pas sûr de la difficulté. Cela vous semble-t-il viable? Je suis dans une start-up à un stade précoce, donc nous ne serons peut-être pas en mesure d'ouvrir l'open source jusqu'à ce que nous ayons des investisseurs :). –

+0

librdkafka fournit une interface asynchrone non bloquante, toutes les opérations d'E/S sont exécutées dans les threads d'arrière-plan, vous devriez donc vous contenter de simplement utiliser le répartiteur d'événements Cap'n comme boucle principale. – Edenhill

+0

@JamesFremen J'ai signalé l'implémentation de libuv comme un exemple d'intégration de KJ avec une boucle d'événement externe. Je ne suis pas au courant de problèmes de performance ou d'autres problèmes majeurs dans le code de colle KJ-UV. C'est entièrement zéro-copie. A moins que l'interface de bas niveau de Kafka ne soit très mauvaise, vous devriez être capable de l'intégrer de cette manière. –