##// END OF EJS Templates
repository: formalize wire protocol interface...
Gregory Szorc -
r33800:558f5b2e default
parent child Browse files
Show More
@@ -1,71 +1,232
1 # repository.py - Interfaces and base classes for repositories and peers.
1 # repository.py - Interfaces and base classes for repositories and peers.
2 #
2 #
3 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import abc
10 import abc
11
11
12 class _basepeer(object):
12 class _basepeer(object):
13 """Represents a "connection" to a repository.
13 """Represents a "connection" to a repository.
14
14
15 This is the base interface for representing a connection to a repository.
15 This is the base interface for representing a connection to a repository.
16 It holds basic properties and methods applicable to all peer types.
16 It holds basic properties and methods applicable to all peer types.
17
17
18 This is not a complete interface definition and should not be used
18 This is not a complete interface definition and should not be used
19 outside of this module.
19 outside of this module.
20 """
20 """
21 __metaclass__ = abc.ABCMeta
21 __metaclass__ = abc.ABCMeta
22
22
23 @abc.abstractproperty
23 @abc.abstractproperty
24 def ui(self):
24 def ui(self):
25 """ui.ui instance."""
25 """ui.ui instance."""
26
26
27 @abc.abstractmethod
27 @abc.abstractmethod
28 def url(self):
28 def url(self):
29 """Returns a URL string representing this peer.
29 """Returns a URL string representing this peer.
30
30
31 Currently, implementations expose the raw URL used to construct the
31 Currently, implementations expose the raw URL used to construct the
32 instance. It may contain credentials as part of the URL. The
32 instance. It may contain credentials as part of the URL. The
33 expectations of the value aren't well-defined and this could lead to
33 expectations of the value aren't well-defined and this could lead to
34 data leakage.
34 data leakage.
35
35
36 TODO audit/clean consumers and more clearly define the contents of this
36 TODO audit/clean consumers and more clearly define the contents of this
37 value.
37 value.
38 """
38 """
39
39
40 @abc.abstractmethod
40 @abc.abstractmethod
41 def local(self):
41 def local(self):
42 """Returns a local repository instance.
42 """Returns a local repository instance.
43
43
44 If the peer represents a local repository, returns an object that
44 If the peer represents a local repository, returns an object that
45 can be used to interface with it. Otherwise returns ``None``.
45 can be used to interface with it. Otherwise returns ``None``.
46 """
46 """
47
47
48 @abc.abstractmethod
48 @abc.abstractmethod
49 def peer(self):
49 def peer(self):
50 """Returns an object conforming to this interface.
50 """Returns an object conforming to this interface.
51
51
52 Most implementations will ``return self``.
52 Most implementations will ``return self``.
53 """
53 """
54
54
55 @abc.abstractmethod
55 @abc.abstractmethod
56 def canpush(self):
56 def canpush(self):
57 """Returns a boolean indicating if this peer can be pushed to."""
57 """Returns a boolean indicating if this peer can be pushed to."""
58
58
59 @abc.abstractmethod
59 @abc.abstractmethod
60 def close(self):
60 def close(self):
61 """Close the connection to this peer.
61 """Close the connection to this peer.
62
62
63 This is called when the peer will no longer be used. Resources
63 This is called when the peer will no longer be used. Resources
64 associated with the peer should be cleaned up.
64 associated with the peer should be cleaned up.
65 """
65 """
66
66
67 class peer(_basepeer):
67 class _basewirecommands(object):
68 """Client-side interface for communicating over the wire protocol.
69
70 This interface is used as a gateway to the Mercurial wire protocol.
71 methods commonly call wire protocol commands of the same name.
72 """
73 __metaclass__ = abc.ABCMeta
74
75 @abc.abstractmethod
76 def branchmap(self):
77 """Obtain heads in named branches.
78
79 Returns a dict mapping branch name to an iterable of nodes that are
80 heads on that branch.
81 """
82
83 @abc.abstractmethod
84 def capabilities(self):
85 """Obtain capabilities of the peer.
86
87 Returns a set of string capabilities.
88 """
89
90 @abc.abstractmethod
91 def debugwireargs(self, one, two, three=None, four=None, five=None):
92 """Used to facilitate debugging of arguments passed over the wire."""
93
94 @abc.abstractmethod
95 def getbundle(self, source, **kwargs):
96 """Obtain remote repository data as a bundle.
97
98 This command is how the bulk of repository data is transferred from
99 the peer to the local repository
100
101 Returns a generator of bundle data.
102 """
103
104 @abc.abstractmethod
105 def heads(self):
106 """Determine all known head revisions in the peer.
107
108 Returns an iterable of binary nodes.
109 """
110
111 @abc.abstractmethod
112 def known(self, nodes):
113 """Determine whether multiple nodes are known.
114
115 Accepts an iterable of nodes whose presence to check for.
116
117 Returns an iterable of booleans indicating of the corresponding node
118 at that index is known to the peer.
119 """
120
121 @abc.abstractmethod
122 def listkeys(self, namespace):
123 """Obtain all keys in a pushkey namespace.
124
125 Returns an iterable of key names.
126 """
127
128 @abc.abstractmethod
129 def lookup(self, key):
130 """Resolve a value to a known revision.
131
132 Returns a binary node of the resolved revision on success.
133 """
134
135 @abc.abstractmethod
136 def pushkey(self, namespace, key, old, new):
137 """Set a value using the ``pushkey`` protocol.
138
139 Arguments correspond to the pushkey namespace and key to operate on and
140 the old and new values for that key.
141
142 Returns a string with the peer result. The value inside varies by the
143 namespace.
144 """
145
146 @abc.abstractmethod
147 def stream_out(self):
148 """Obtain streaming clone data.
149
150 Successful result should be a generator of data chunks.
151 """
152
153 @abc.abstractmethod
154 def unbundle(self, bundle, heads, url):
155 """Transfer repository data to the peer.
156
157 This is how the bulk of data during a push is transferred.
158
159 Returns the integer number of heads added to the peer.
160 """
161
162 class _baselegacywirecommands(object):
163 """Interface for implementing support for legacy wire protocol commands.
164
165 Wire protocol commands transition to legacy status when they are no longer
166 used by modern clients. To facilitate identifying which commands are
167 legacy, the interfaces are split.
168 """
169 __metaclass__ = abc.ABCMeta
170
171 @abc.abstractmethod
172 def between(self, pairs):
173 """Obtain nodes between pairs of nodes.
174
175 ``pairs`` is an iterable of node pairs.
176
177 Returns an iterable of iterables of nodes corresponding to each
178 requested pair.
179 """
180
181 @abc.abstractmethod
182 def branches(self, nodes):
183 """Obtain ancestor changesets of specific nodes back to a branch point.
184
185 For each requested node, the peer finds the first ancestor node that is
186 a DAG root or is a merge.
187
188 Returns an iterable of iterables with the resolved values for each node.
189 """
190
191 @abc.abstractmethod
192 def changegroup(self, nodes, kind):
193 """Obtain a changegroup with data for descendants of specified nodes."""
194
195 @abc.abstractmethod
196 def changegroupsubset(self, bases, heads, kind):
197 pass
198
199 class peer(_basepeer, _basewirecommands):
68 """Unified interface and base class for peer repositories.
200 """Unified interface and base class for peer repositories.
69
201
70 All peer instances must inherit from this class.
202 All peer instances must inherit from this class and conform to its
203 interface.
71 """
204 """
205
206 @abc.abstractmethod
207 def iterbatch(self):
208 """Obtain an object to be used for multiple method calls.
209
210 Various operations call several methods on peer instances. If each
211 method call were performed immediately and serially, this would
212 require round trips to remote peers and/or would slow down execution.
213
214 Some peers have the ability to "batch" method calls to avoid costly
215 round trips or to facilitate concurrent execution.
216
217 This method returns an object that can be used to indicate intent to
218 perform batched method calls.
219
220 The returned object is a proxy of this peer. It intercepts calls to
221 batchable methods and queues them instead of performing them
222 immediately. This proxy object has a ``submit`` method that will
223 perform all queued batchable method calls. A ``results()`` method
224 exposes the results of queued/batched method calls. It is a generator
225 of results in the order they were called.
226
227 Not all peers or wire protocol implementations may actually batch method
228 calls. However, they must all support this API.
229 """
230
231 class legacypeer(peer, _baselegacywirecommands):
232 """peer but with support for legacy wire protocol commands."""
General Comments 0
You need to be logged in to leave comments. Login now