Revision 0cdb8b3c ncclient/operations/rpc.py
b/ncclient/operations/rpc.py | ||
---|---|---|
17 | 17 |
from weakref import WeakValueDictionary |
18 | 18 |
|
19 | 19 |
from ncclient import content |
20 |
from ncclient.transport import SessionListener |
|
20 | 21 |
|
21 | 22 |
from errors import OperationError |
22 | 23 |
|
... | ... | |
45 | 46 |
return |
46 | 47 |
root = self._root = content.xml2ele(self._raw) # <rpc-reply> element |
47 | 48 |
# per rfc 4741 an <ok/> tag is sent when there are no errors or warnings |
48 |
ok = content.find(root, 'ok')
|
|
49 |
ok = content.find(root, 'data', strict=False)
|
|
49 | 50 |
if ok is not None: |
50 | 51 |
logger.debug('parsed [%s]' % ok.tag) |
51 | 52 |
else: # create RPCError objects from <rpc-error> elements |
52 |
error = content.find(root, 'rpc-error')
|
|
53 |
error = content.find(root, 'data', strict=False)
|
|
53 | 54 |
if error is not None: |
54 | 55 |
logger.debug('parsed [%s]' % error.tag) |
55 | 56 |
for err in root.getiterator(error.tag): |
... | ... | |
151 | 152 |
__repr__ = lambda self: repr(self._dict) |
152 | 153 |
|
153 | 154 |
|
154 |
class RPCReplyListener(object):
|
|
155 |
class RPCReplyListener(SessionListener):
|
|
155 | 156 |
|
156 | 157 |
# one instance per session |
157 | 158 |
def __new__(cls, session): |
... | ... | |
161 | 162 |
instance._lock = Lock() |
162 | 163 |
instance._id2rpc = WeakValueDictionary() |
163 | 164 |
instance._pipelined = session.can_pipeline |
164 |
instance._errback = None |
|
165 | 165 |
session.add_listener(instance) |
166 | 166 |
return instance |
167 | 167 |
|
168 | 168 |
def register(self, id, rpc): |
169 | 169 |
with self._lock: |
170 | 170 |
self._id2rpc[id] = rpc |
171 |
|
|
172 |
def set_errback(self, errback): |
|
173 |
self._errback = errback |
|
174 | 171 |
|
175 | 172 |
def callback(self, root, raw): |
176 | 173 |
tag, attrs = root |
... | ... | |
200 | 197 |
rpc.deliver(raw) |
201 | 198 |
|
202 | 199 |
def errback(self, err): |
203 |
if self._errback is not None:
|
|
204 |
self._errback(err)
|
|
200 |
for rpc in self._id2rpc.values():
|
|
201 |
rpc.error(err)
|
|
205 | 202 |
|
206 | 203 |
|
207 | 204 |
class RPC(object): |
... | ... | |
241 | 238 |
req = self._build(op) |
242 | 239 |
self._session.send(req) |
243 | 240 |
if self._async: |
244 |
return self._reply_event
|
|
241 |
return (self._reply_event, self._error_event)
|
|
245 | 242 |
else: |
246 | 243 |
self._reply_event.wait(self._timeout) |
247 |
if self._reply_event.isSet(): |
|
244 |
if self._reply_event.is_set(): |
|
245 |
if self._error: |
|
246 |
raise self._error |
|
248 | 247 |
self._reply.parse() |
249 | 248 |
return self._reply |
250 | 249 |
else: |
... | ... | |
266 | 265 |
self._delivery_hook() |
267 | 266 |
self._reply_event.set() |
268 | 267 |
|
268 |
def error(self, err): |
|
269 |
self._error = err |
|
270 |
self._reply_event.set() |
|
271 |
|
|
269 | 272 |
@property |
270 | 273 |
def has_reply(self): |
271 |
return self._reply_event.isSet()
|
|
274 |
return self._reply_event.is_set()
|
|
272 | 275 |
|
273 | 276 |
@property |
274 | 277 |
def reply(self): |
Also available in: Unified diff