]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/util/rrefutil.py
switch all foolscap imports to use foolscap.api or foolscap.logging
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / util / rrefutil.py
1 import exceptions
2
3 from foolscap.api import Violation
4
5 class ServerFailure(exceptions.Exception):
6     # If the server returns a Failure instead of the normal response to a
7     # protocol, then this exception will be raised, with the Failure that the
8     # server returned as its .remote_failure attribute.
9     def __init__(self, remote_failure):
10         self.remote_failure = remote_failure
11     def __repr__(self):
12         return repr(self.remote_failure)
13     def __str__(self):
14         return str(self.remote_failure)
15
16 def is_remote(f):
17     if isinstance(f.value, ServerFailure):
18         return True
19     return False
20
21 def is_local(f):
22     return not is_remote(f)
23
24 def check_remote(f, *errorTypes):
25     if is_remote(f):
26         return f.value.remote_failure.check(*errorTypes)
27     return None
28
29 def check_local(f, *errorTypes):
30     if is_local(f):
31         return f.check(*errorTypes)
32     return None
33
34 def trap_remote(f, *errorTypes):
35     if is_remote(f):
36         return f.value.remote_failure.trap(*errorTypes)
37     raise f
38
39 def trap_local(f, *errorTypes):
40     if is_local(f):
41         return f.trap(*errorTypes)
42     raise f
43
44 def _wrap_server_failure(f):
45     raise ServerFailure(f)
46
47 class WrappedRemoteReference(object):
48     """I intercept any errback from the server and wrap it in a
49     ServerFailure."""
50
51     def __init__(self, original):
52         self.rref = original
53
54     def callRemote(self, *args, **kwargs):
55         d = self.rref.callRemote(*args, **kwargs)
56         d.addErrback(_wrap_server_failure)
57         return d
58
59     def callRemoteOnly(self, *args, **kwargs):
60         return self.rref.callRemoteOnly(*args, **kwargs)
61
62     def notifyOnDisconnect(self, *args, **kwargs):
63         return self.rref.notifyOnDisconnect(*args, **kwargs)
64
65     def dontNotifyOnDisconnect(self, *args, **kwargs):
66         return self.rref.dontNotifyOnDisconnect(*args, **kwargs)
67
68 class VersionedRemoteReference(WrappedRemoteReference):
69     """I wrap a RemoteReference, and add a .version attribute. I also
70     intercept any errback from the server and wrap it in a ServerFailure."""
71
72     def __init__(self, original, version):
73         WrappedRemoteReference.__init__(self, original)
74         self.version = version
75
76 def get_versioned_remote_reference(rref, default):
77     """I return a Deferred that fires with a VersionedRemoteReference"""
78     d = rref.callRemote("get_version")
79     def _no_get_version(f):
80         f.trap(Violation, AttributeError)
81         return default
82     d.addErrback(_no_get_version)
83     def _got_version(version):
84         return VersionedRemoteReference(rref, version)
85     d.addCallback(_got_version)
86     return d
87