Mercurial > libervia-backend
comparison src/bridge/bridge_constructor/constructors/pb/pb_frontend_template.py @ 2092:5e79ba00c1e2
bridbe(pb): Perspective Broker bridge, first draft
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Dec 2016 22:27:49 +0100 |
parents | |
children | 8b37a62336c3 |
comparison
equal
deleted
inserted
replaced
2091:f413bfc24458 | 2092:5e79ba00c1e2 |
---|---|
1 #!/usr/bin/env python2 | |
2 #-*- coding: utf-8 -*- | |
3 | |
4 # SAT communication bridge | |
5 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from sat.core.log import getLogger | |
21 log = getLogger(__name__) | |
22 from sat.core import exceptions | |
23 from twisted.spread import pb | |
24 from twisted.internet import reactor | |
25 | |
26 | |
27 class SignalsHandler(pb.Referenceable): | |
28 | |
29 def __getattr__(self, name): | |
30 if name.startswith("remote_"): | |
31 log.debug(u"calling an unregistered signal: {name}".format( | |
32 name = name[7:])) | |
33 return lambda *args, **kwargs: None | |
34 | |
35 else: | |
36 raise AttributeError(name) | |
37 | |
38 def register_signal(self, name, handler, iface="core"): | |
39 log.debug("registering signal {name}".format(name=name)) | |
40 method_name = "remote_" + name | |
41 try: | |
42 self.__getattribute__(self, method_name) | |
43 except AttributeError: | |
44 pass | |
45 else: | |
46 raise exceptions.InternalError(u"{name} signal handler has been registered twice".format( | |
47 name = method_name)) | |
48 setattr(self, method_name, handler) | |
49 | |
50 | |
51 class Bridge(object): | |
52 | |
53 def __init__(self): | |
54 self.signals_handler = SignalsHandler() | |
55 | |
56 def __getattr__(self, name): | |
57 return lambda *args, **kwargs: self.call(name, args, kwargs) | |
58 | |
59 def remoteCallback(self, result, callback): | |
60 """call callback with argument or None | |
61 | |
62 if result is not None not argument is used, | |
63 else result is used as argument | |
64 @param result: remote call result | |
65 @param callback(callable): method to call on result | |
66 """ | |
67 if result is None: | |
68 callback() | |
69 else: | |
70 callback(result) | |
71 | |
72 def call(self, name, args, kwargs): | |
73 """call a remote method | |
74 | |
75 @param name(str): name of the bridge method | |
76 @param args(list): arguments | |
77 may contain callback and errback as last 2 items | |
78 @param kwargs(dict): keyword arguments | |
79 may contain callback and errback | |
80 """ | |
81 callback = errback = None | |
82 if kwargs: | |
83 try: | |
84 callback = kwargs.pop('callback') | |
85 except KeyError: | |
86 pass | |
87 try: | |
88 errback = kwargs.pop('errback') | |
89 except KeyError: | |
90 pass | |
91 elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]): | |
92 errback = args.pop() | |
93 callback = args.pop() | |
94 d = self.root.callRemote(name, *args, **kwargs) | |
95 if callback is not None: | |
96 d.addCallback(self.remoteCallback, callback) | |
97 if errback is not None: | |
98 d.addErrback(errback) | |
99 | |
100 def _initBridgeEb(self, failure): | |
101 log.error(u"Can't init bridge: {msg}".format(msg=failure)) | |
102 | |
103 def _set_root(self, root): | |
104 """set remote root object | |
105 | |
106 bridge will then be initialised | |
107 """ | |
108 self.root = root | |
109 d = root.callRemote("initBridge", self.signals_handler) | |
110 d.addErrback(self._initBridgeEb) | |
111 return d | |
112 | |
113 def _generic_errback(self, failure): | |
114 log.error(u"bridge failure: {}".format(failure)) | |
115 | |
116 def bridgeConnect(self, callback, errback): | |
117 factory = pb.PBClientFactory() | |
118 reactor.connectTCP("localhost", 8789, factory) | |
119 d = factory.getRootObject() | |
120 d.addCallback(self._set_root) | |
121 d.addCallback(lambda dummy: callback()) | |
122 d.addErrback(errback) | |
123 | |
124 def register_signal(self, functionName, handler, iface="core"): | |
125 self.signals_handler.register_signal(functionName, handler, iface) | |
126 | |
127 ##METHODS_PART## |