Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

[wamp] self.call() vs self.publish/subscribe() vs self.method()

+1 vote

A Force de me prendre la tete avec des tests je ne sais plus quand il faut faire quoi avec WAMP.

Donc ma question est quand faut-il utiliser tantôt l'un des 4 :

 yield self.call(u'une.procedure.registered')
 yield self.subscribe(on_fonction_qui_se_declenche_quand_leventment_a_lieu, 'procedure.registered')
 yield self.publish('procedure.registered', donnees)
 self.method()

De ce que j'ai constate, coté composant qui subscribe, dans la methode on_fonction_qui_se_declenche_quand_leventment_a_lieu, on oublie le self.call(),
je n'ai aucune erreur dans les logs mais la procedure que j'appelle ne l'est jamais (appelée), et donc, on fait un self.method()

exemple :

ca ca marche pas :

@inlineCallbacks
def onJoin(self, details):
    def on_event(data):
        yield self.call('eu.trigger-happy.evernote.save', data)

    try:
        yield self.subscribe(on_event, u'eu.trigger-happy.rss')
        print("subscribe topic")
    except Exception as e:
        print("could not subscribe to topic: {0}".format(e))

@wamp.register(u'eu.trigger-happy.evernote.save')
@inlineCallbacks
def save_data(self, stuff):
    print("je sauve")
    print (json.dumps(stuff, indent=4))

alors que ca ca marche

@inlineCallbacks
def onJoin(self, details):
    def on_event(data):
        self.save_data(data)

    try:
        yield self.subscribe(on_event, u'eu.trigger-happy.rss')
        print("subscribe topic")
    except Exception as e:
        print("could not subscribe to topic: {0}".format(e))

def save_data(self, stuff):
    print("je sauve")
    print(json.dumps(stuff, indent=4))

Coté publisher j'ai pu cascader des yield self.call() d'une procédure à l'autre, non sans mal, mais coté subscriber j'ai l'impression que c'est à proscrire.

J'ai aussi des problèmes de sérialisations qui ne passe meme pas avec pickle mais j'en reparlerai dans un thread déjà ouvert

Actuellment je n'ai rien trouvé comme exemple de transcandant qui permette d'utiliser des appels à une base, traiter les données (avec des dates :P) les refiler au voisin (une autre procédure) passer au subscriber etc.

En tout cas ca fait 2semaines que je planche (l'entetement:P) et je ne trouve de réponse ni sur le ML ni sur le channel irc du projet .
L'impression de naviguer à vue.

Avez vous des suggestions / exemples documentés ?

demandé 23-Fev-2015 par foxmask (2,874 points)

1 Réponse

0 votes
 
Meilleure réponse

inlineCallbacks est un décorateur pour écrire du code asynchrone sans utiliser de callback. Jette un coup d’œil à cette PR.

Du coup, dans ton premier code, la fonction on_event devrait être décorée puisqu'elle exécute du code asynchrone, avec l'appel RPC. Par contre, save_data n'a aucune raison d'être décorée par inlineCallbacks vu que tu ne fais pas d'appel asynchrone dedans. En revanche, si tu veux pouvoir l'appeler via RPC, il faut effectivement la décorer avec wamp.register.

Quant à la question de si tu dois enregistrer save_data en tant que procédure... tout dépend de ton app. Tu peux jeter un coup d'oeil à ça, avec un exemple d'utilisation ici. A noter que tu peux faire ça :

from twisted.internet.defer import inlineCallbacks

from autobahn.twisted.util import sleep
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError



class Component(ApplicationSession):

    @inlineCallbacks
    def onJoin(self, details):
        while True:
            try:
                yield self.call(u'com.app.reg', 42)
                yield self.call(u'com.app.reg_', "by Autobahn")
            except ApplicationError as e:
                if e.error != 'wamp.error.no_such_procedure':
                    raise e

            yield sleep(2)

Avec un register de la sorte :

from autobahn import wamp
from autobahn.twisted.wamp import ApplicationSession



class Component(ApplicationSession):

    def onJoin(self, details):
        self.register(self)
        self.subscribe(self)

    @wamp.register(u'com.app.reg_')
    def reg_(self, method):
        print("Register called {}.".format(method))

    @wamp.register(u'com.app.reg')
    def reg(self, *args):
        print("Component 2 received: {}".format(args))
        self.reg_("manually")

Une règle donc : code asynchrone dans la fonction => fonction décorée par inlineCallbacks. Sauf si tu préfères travailler avec les callbacks.

répondu 24-Fev-2015 par Vayel (1,050 points)
edité 27-Fev-2015 par Vayel

du coup quel est :

1) le mieux ?
2) le plus utilisé dans les règles de l'art ?

callbacks ou appel RPC ?

pour save_data ; l'enregistrer où non, quel est le critère qui permet de decider si j'enregistre la procédure ou pas ?
là ca sera jamais que utiliser par le module courant, est-ce un critère qui permette d'orienter le choix ?

y a -t-il un impact sur les perf à faire du RPC à outrance ou ca ne se justifie pas plus que ca et des appels à des callback suffisent largement ?

tester ; ca me va au poil - par contre si tu peux m'apporter des précisions à mon commentaire précédant ca serait cool

Tu enregistres la procédure si tu as besoin de l'appeler depuis l'extérieur. Sinon, il n'y a pas d'intérêt.

Au niveau des performances, il est clair que passer par RPC est plus consommateur qu'un appel direct.

Par contre, je ne comprends pas trop ce que tu appelles "appels à des callback".

Ok merci ; c'est clair à présent

donc yield self.call('procedure') permettrait d'appeler une methode d'un autre composant ?
Si oui, Mais comment ?

ce que j'appellais callback c'est la methode decoree par @inlineCallback
je tatonne encore sur le vocable à employer pour utiliser la bete ;)

Je vais essayer d'écrire un article pour clarifier ça.

ok ;)
parce que j'en ai préparé un sur mes tribulations de cette semaine ; avec ces précisions je pourrai le sortir

Réponse mise à jour.

...