##// END OF EJS Templates
peer: use absolute_import
Gregory Szorc -
r25965:e6b56b2c default
parent child Browse files
Show More
@@ -1,122 +1,126
1 1 # peer.py - repository base classes for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 from i18n import _
10 import error
11 import util
9 from __future__ import absolute_import
10
11 from .i18n import _
12 from . import (
13 error,
14 util,
15 )
12 16
13 17 # abstract batching support
14 18
15 19 class future(object):
16 20 '''placeholder for a value to be set later'''
17 21 def set(self, value):
18 22 if util.safehasattr(self, 'value'):
19 23 raise error.RepoError("future is already set")
20 24 self.value = value
21 25
22 26 class batcher(object):
23 27 '''base class for batches of commands submittable in a single request
24 28
25 29 All methods invoked on instances of this class are simply queued and
26 30 return a a future for the result. Once you call submit(), all the queued
27 31 calls are performed and the results set in their respective futures.
28 32 '''
29 33 def __init__(self):
30 34 self.calls = []
31 35 def __getattr__(self, name):
32 36 def call(*args, **opts):
33 37 resref = future()
34 38 self.calls.append((name, args, opts, resref,))
35 39 return resref
36 40 return call
37 41 def submit(self):
38 42 pass
39 43
40 44 class localbatch(batcher):
41 45 '''performs the queued calls directly'''
42 46 def __init__(self, local):
43 47 batcher.__init__(self)
44 48 self.local = local
45 49 def submit(self):
46 50 for name, args, opts, resref in self.calls:
47 51 resref.set(getattr(self.local, name)(*args, **opts))
48 52
49 53 def batchable(f):
50 54 '''annotation for batchable methods
51 55
52 56 Such methods must implement a coroutine as follows:
53 57
54 58 @batchable
55 59 def sample(self, one, two=None):
56 60 # Handle locally computable results first:
57 61 if not one:
58 62 yield "a local result", None
59 63 # Build list of encoded arguments suitable for your wire protocol:
60 64 encargs = [('one', encode(one),), ('two', encode(two),)]
61 65 # Create future for injection of encoded result:
62 66 encresref = future()
63 67 # Return encoded arguments and future:
64 68 yield encargs, encresref
65 69 # Assuming the future to be filled with the result from the batched
66 70 # request now. Decode it:
67 71 yield decode(encresref.value)
68 72
69 73 The decorator returns a function which wraps this coroutine as a plain
70 74 method, but adds the original method as an attribute called "batchable",
71 75 which is used by remotebatch to split the call into separate encoding and
72 76 decoding phases.
73 77 '''
74 78 def plain(*args, **opts):
75 79 batchable = f(*args, **opts)
76 80 encargsorres, encresref = batchable.next()
77 81 if not encresref:
78 82 return encargsorres # a local result in this case
79 83 self = args[0]
80 84 encresref.set(self._submitone(f.func_name, encargsorres))
81 85 return batchable.next()
82 86 setattr(plain, 'batchable', f)
83 87 return plain
84 88
85 89 class peerrepository(object):
86 90
87 91 def batch(self):
88 92 return localbatch(self)
89 93
90 94 def capable(self, name):
91 95 '''tell whether repo supports named capability.
92 96 return False if not supported.
93 97 if boolean capability, return True.
94 98 if string capability, return string.'''
95 99 caps = self._capabilities()
96 100 if name in caps:
97 101 return True
98 102 name_eq = name + '='
99 103 for cap in caps:
100 104 if cap.startswith(name_eq):
101 105 return cap[len(name_eq):]
102 106 return False
103 107
104 108 def requirecap(self, name, purpose):
105 109 '''raise an exception if the given capability is not present'''
106 110 if not self.capable(name):
107 111 raise error.CapabilityError(
108 112 _('cannot %s; remote repository does not '
109 113 'support the %r capability') % (purpose, name))
110 114
111 115 def local(self):
112 116 '''return peer as a localrepo, or None'''
113 117 return None
114 118
115 119 def peer(self):
116 120 return self
117 121
118 122 def canpush(self):
119 123 return True
120 124
121 125 def close(self):
122 126 pass
General Comments 0
You need to be logged in to leave comments. Login now