annotate mercurial/peer.py @ 34733:115efdd97088

peer: ensure command names are always ascii bytestrs Differential Revision: https://phab.mercurial-scm.org/D1104
author Augie Fackler <augie@google.com>
date Sun, 15 Oct 2017 00:05:00 -0400
parents a652b7763f66
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 17191
diff changeset
1 # peer.py - repository base classes for mercurial
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
2 #
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3930
diff changeset
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
5 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
6 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9436
diff changeset
7 # GNU General Public License version 2 or any later version.
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
8
25965
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
9 from __future__ import absolute_import
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
10
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
11 from . import (
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
12 error,
34733
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
13 pycompat,
25965
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
14 util,
e6b56b2c1f26 peer: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25912
diff changeset
15 )
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
16
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
17 # abstract batching support
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
18
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
19 class future(object):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
20 '''placeholder for a value to be set later'''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
21 def set(self, value):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
22 if util.safehasattr(self, 'value'):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
23 raise error.RepoError("future is already set")
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
24 self.value = value
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
25
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
26 class batcher(object):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
27 '''base class for batches of commands submittable in a single request
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
28
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
29 All methods invoked on instances of this class are simply queued and
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
30 return a a future for the result. Once you call submit(), all the queued
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
31 calls are performed and the results set in their respective futures.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
32 '''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
33 def __init__(self):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
34 self.calls = []
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
35 def __getattr__(self, name):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
36 def call(*args, **opts):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
37 resref = future()
34727
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
38 # Please don't invent non-ascii method names, or you will
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
39 # give core hg a very sad time.
a652b7763f66 peer: when collecting method names for batch calls, bytes-ify __name__
Augie Fackler <augie@google.com>
parents: 34693
diff changeset
40 self.calls.append((name.encode('ascii'), args, opts, resref,))
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
41 return resref
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
42 return call
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
43 def submit(self):
28434
d549cbb5503d peer: raise NotImplementedError for abstract submit() method
Augie Fackler <augie@google.com>
parents: 25965
diff changeset
44 raise NotImplementedError()
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
45
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
46 class iterbatcher(batcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
47
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
48 def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
49 raise NotImplementedError()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
50
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
51 def results(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
52 raise NotImplementedError()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
53
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
54 class localiterbatcher(iterbatcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
55 def __init__(self, local):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
56 super(iterbatcher, self).__init__()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
57 self.local = local
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
58
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
59 def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
60 # submit for a local iter batcher is a noop
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
61 pass
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
62
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
63 def results(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
64 for name, args, opts, resref in self.calls:
33787
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33786
diff changeset
65 resref.set(getattr(self.local, name)(*args, **opts))
4c706037adef wireproto: overhaul iterating batcher code (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33786
diff changeset
66 yield resref.value
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28434
diff changeset
67
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
68 def batchable(f):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
69 '''annotation for batchable methods
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
70
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
71 Such methods must implement a coroutine as follows:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
72
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
73 @batchable
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
74 def sample(self, one, two=None):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
75 # Build list of encoded arguments suitable for your wire protocol:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
76 encargs = [('one', encode(one),), ('two', encode(two),)]
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
77 # Create future for injection of encoded result:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
78 encresref = future()
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
79 # Return encoded arguments and future:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
80 yield encargs, encresref
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
81 # Assuming the future to be filled with the result from the batched
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
82 # request now. Decode it:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
83 yield decode(encresref.value)
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
84
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
85 The decorator returns a function which wraps this coroutine as a plain
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
86 method, but adds the original method as an attribute called "batchable",
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
87 which is used by remotebatch to split the call into separate encoding and
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
88 decoding phases.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
89 '''
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
90 def plain(*args, **opts):
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
91 batchable = f(*args, **opts)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28436
diff changeset
92 encargsorres, encresref = next(batchable)
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
93 if not encresref:
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
94 return encargsorres # a local result in this case
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
95 self = args[0]
34733
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
96 cmd = pycompat.bytesurl(f.__name__) # ensure cmd is ascii bytestr
115efdd97088 peer: ensure command names are always ascii bytestrs
Augie Fackler <augie@google.com>
parents: 34727
diff changeset
97 encresref.set(self._submitone(cmd, encargsorres))
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28436
diff changeset
98 return next(batchable)
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
99 setattr(plain, 'batchable', f)
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 17273
diff changeset
100 return plain