2017-01-18 3 views
1

Je voudrais essayer promettre pipelining avec Cap'n Proto C++ RPC mais je ne sais pas comment le faire.Cap'n Proto et promettre pipelining

Voici mon schéma:

interface Test { 
    getInt @0() -> (intResult :Int32); 
    increment @1 (intParam :Int32) -> (intResult :Int32); 
} 

Voici ce que je voudrais faire (pseudo-code):

increment(getInt()); 

J'ai essayé de faire quelque chose comme ça:

auto request1 = test.getIntRequest(); 
auto promise = request1.send(); 

auto request2 = test.incrementRequest(); 
request2.setIntParam(promise.getIntResult()) // HERE IS THE PROBLEM 
auto promise2 = request2.send(); 

mais ce n'est pas la bonne façon d'utiliser les promesses. J'espère que vous comprenez ce que je veux faire.

Merci.

EDIT: une autre question: comment implémenter les méthodes sur le serveur?

J'ai écrit ce code:

#include <kj/debug.h> 
#include <capnp/ez-rpc.h> 
#include <capnp/message.h> 
#include <iostream> 
#include "test.capnp.h" 

using namespace std; 


class TestI : virtual public Test::Server 
{ 
public: 
     TestI() {} 
     ::kj::Promise<void> getInt(GetIntContext context) 
     { 
      // ???? 
     } 
     ::kj::Promise<void> increment(IncrementContext context) 
     { 
      // ???? 
     } 
}; 

class Int32BoxI : virtual public Int32Box::Server 
{ 
private: 
     int val = 12; 
public: 
     Int32BoxI(int value): val(value) {} 
     ::kj::Promise<void> get(GetContext context) 
     { 
      context.getResults().setValue(this->val); 
      return kj::READY_NOW; 
     } 
} 

mais je ne sais pas comment mettre en œuvre getInt() et l'incrément().

Répondre

2

Le problème ici est que vous essayez de pipeline sur un int, mais le traitement en pipeline ne fonctionne qu'avec des références d'objet. Vous pouvez résoudre ceci en enveloppant l'int dans un objet, comme ceci:

interface Int32Box { 
    get @0() -> (value :Int32); 
} 

interface Test { 
    getInt @0() -> (intResult :Int32Box); 
    increment @1 (intParam :Int32Box) -> (intResult :Int32Box); 
} 

Maintenant votre code fonctionnera comme écrit.

Bien sûr, vous devez maintenant appeler .get() sur le Int32Box final pour lire la valeur. Heureusement, vous pouvez canaliser cet appel, de sorte qu'il ne nécessite aucun tour supplémentaire du réseau.

auto request1 = test.getIntRequest(); 
auto promise = request1.send(); 

auto request2 = test.incrementRequest(); 
request2.setIntParam(promise.getIntResult()); 
auto promise2 = request2.send(); 

auto request3 = promise2.getIntResult().getRequest(); 
auto promise3 = request3.send(); 

// This is the only wait! 
int finalResult = promise3.wait().getValue(); 

La séquence ci-dessus s'exécute avec un seul aller-retour réseau.

+0

Merci pour votre réponse. C'est plus clair pour moi maintenant. Cependant, j'ai quelques difficultés à implémenter les méthodes sur le serveur. J'ai édité mon premier article pour vous montrer mon problème. Merci encore. –

+1

@ B.Clement Je recommande de consulter l'exemple de "calculatrice" dans le dépôt Cap'n Proto - il est très similaire à ce que vous faites. Voir: https://github.com/sandstorm-io/capnproto/tree/master/c++/samples –