Commit Graph

260 Commits

Author SHA1 Message Date
Pierre-Yves David
3385347d38 bundle2: decorate exception raised during bundle processing
This is a small hack to help us do some graceful error handling in bundle2
without major refactoring. See embedded comment for details.
2014-04-22 11:22:41 -07:00
Pierre-Yves David
fd614e4d04 bundle2: move all parts into a bx2 namespace
All currently core parts are moved to a `bx2` namespace (for "bundle 2
experimental"). This should avoid conflicts between the final stable
format and the one about to be released.
2014-04-17 15:45:12 -04:00
Pierre-Yves David
7e653a9c0f bundle2: use HG2X in the header
The current implementation of bundle2 is still very experimental and the 3.0
freeze is yesterday. The current bundle2 format has never been field-tested, so
we rename the header to HG2X. This leaves the HG20 header available for real
usage as a stable format in Mercurial 3.1.

We won't guarantee that future mercurial versions will keep supporting this
`HG2X` format.
2014-04-17 15:27:54 -04:00
Pierre-Yves David
9bb9dc1703 bundle2: capabilities encoding 2014-04-17 01:44:53 -04:00
Pierre-Yves David
211041404c bundle2: extract capabilities decoding
We'll need to reuse this in more places (at least pull and push).
2014-04-17 01:09:05 -04:00
Pierre-Yves David
f2ead829c7 bundle2: protect capabilities name and values with url quoting
This lift limitations of the text based encoding.
2014-04-17 01:03:33 -04:00
Pierre-Yves David
f48478a77f bundle2: support for capabilities with values
The capabilities attributes of `bundle20` is now a dictionary and the reply caps
can encode capabilities with values.
2014-04-17 11:44:49 -04:00
Pierre-Yves David
b4784becd2 bundle2: add capabilities support in replycaps part
This part now contains a list of supported capabilities.
2014-04-17 11:32:30 -04:00
Pierre-Yves David
e273dad6f6 bundle2: adds a capabilities attribute on bundler20
This attribute conveys the capabilities supported by the destination of the
bundle. It is used to decide which parts to include in the bundle.

This is currently a set but will probably be turned into a dictionary to allow
capabilities with values.
2014-04-16 23:55:59 -04:00
Pierre-Yves David
1c2cd8594e bundle2: include stderr when capturing handlers output
We do not discriminate between stdout and stderr yet. But this will do for now.
2014-04-16 23:18:27 -04:00
Pierre-Yves David
53ffee95a2 bundle2: capture remote stdout while unbundling
When a reply is built, the bundle processing will capture the output of each
handler and sends it to the client in a dedicated part.

As a side effect, this add a "remote: " prefix to destination output on local
push. This is considered okay for now as:

1. bundle2 is still experimental,
2. Matt said he could be okay to change output for bundle2,
3. This keeps the implementation simple.

This changeset does it for stdout only. stderr will be done in a future changeset.
2014-04-16 14:22:24 -04:00
Pierre-Yves David
f7d4dc294b bundle2: introduce replycaps part for on-demand reply
The bundle2 processing does not create a bundle2 reply by default anymore.  It
is only done if the client requests it with a `replycaps` part. This part is
called `replycaps` as it will eventually contain data about which bundle2
capabilities are supported by the client.

We have to add a flag to the test command to control whether a reply is
generated or not.
2014-04-16 14:09:35 -04:00
Pierre-Yves David
88fa4f238f bundle2: use an official iterparts method to unbundle parts
Explicit is better than implicit.
2014-04-16 18:41:48 -04:00
Pierre-Yves David
4ba3ed7539 bundle2: make header reading optional
The `readbundle` function will consume the 4 first bytes to dispatch between
various unbundler. We introduce a way to inform `unbundle20` that the header
has been read and it can be trusted.
2014-04-15 13:54:54 -04:00
Pierre-Yves David
a214f21ef0 bundle2: use headerless HG10UN stream in changegroup
Using `readbundle` in the part handlers creates a circular import hell. We are
now using a simple `HG10UN` stream with no header. Some parameters may
later be introduced on the part to change parameter.

Producers are updated as well.
2014-04-14 14:46:32 -04:00
Pierre-Yves David
6661b09fe1 bundle2: add a "check:heads" handler
This part is intended to hold the same role as the `heads` argument of the
unbundle function. The client fill it with the known heads at bundle time and
the server will abort if its heads changed.
2014-04-11 06:43:01 -07:00
Mads Kiilerich
0e8795ccd6 spelling: fixes from spell checker 2014-04-13 19:01:00 +02:00
Pierre-Yves David
75b8e03941 bundle2: directly feed part to readbundle
Now that part payload can be read like a stream, we can directly use it to feed
the unbundle10 process.
2014-04-12 00:38:15 -04:00
Pierre-Yves David
acbb6d4494 bundle2: lazy unbundle of part payload
The `unbundle` part gains a `read` method to retrieve payload content.
This method behaves as a python file-like read method.

The bundle-processing code is updated to make sure a part is fully consumed before
another one is extracted.

Test output changes because the debug output is even more interleaved now.
2014-04-11 16:05:22 -04:00
Pierre-Yves David
1726c7ed72 bundle2: move unpackheader closure into the class
With the same argument as the other one, we move this closure into the
`unbundlepart` class.
2014-04-11 15:47:38 -04:00
Pierre-Yves David
a5bcb69da6 bundle2: move the fromheader closure into the class itself
The class is now directly related to this header data. We can sanely move it on
the class.

I do not like closures very much...
2014-04-11 15:46:09 -04:00
Pierre-Yves David
0819f89a04 bundle2: add an unbundle part responsible from unbundling part
We have a new unbundle class and it is now responsible from extracting its own
data. The top level bundler only extracts the header (to detect an end of stream
marker) then leaves everything else to the `unbundlepart` class. The ultimate
goal is to have `unbundlepart` responsible for lazily extracting its payload.

This is mostly code movement.
2014-04-11 15:43:16 -04:00
Pierre-Yves David
10657d6382 bundle2: extract stream/unpack logic in an unpackermixin
The coming `unbundlepart` will need the same kind of method than `unbundle20`
for unpacking data from the stream. We extract them into a mixin class before
the creation of `unbundlepart`.
2014-04-11 15:19:54 -04:00
Pierre-Yves David
e5b4ced868 bundle2: rename part to bundlepart
We are going to introduce an `unbundlepart` dedicated to reading bundle. So we
need to rename the one used to create bundle. Even if dedicated to creation, this
is still used for unbundling until we get the new class.
2014-04-11 07:36:14 -07:00
Pierre-Yves David
ef4a1b021a bundle2: comment to clarify why the handler call is where it is
The reason why it is here is not obvious. I'm the one who wrote it there in the
first place and almost moved it 2 weeks later.
2014-04-11 16:43:01 -04:00
Pierre-Yves David
be93303ad1 bundle2: support chunk iterator as part data
When the `part.data` attribute is an iterator, we assume it is an iterator of
chunks and use it.

We use a chunkbuffer to yield chunks of 4096 bytes.

The tests are updated to use this feature.
2014-04-11 08:04:16 -07:00
Pierre-Yves David
2cfe67ddd2 bundle2: extract a _payloadchunks method for part
We are preparing streaming capability for part. So the generation of payload
chunk will becomes more complex. We extract this part in its own function before
any changes.
2014-04-10 12:33:20 -07:00
Pierre-Yves David
c4bb78d90c bundle2: use reply part to return result of addchangegroup
We now have an official way to return the result of addchangegroup. The tests are
updated to check that the return bundle is properly created. It will be used
when push is bundle2 enabled.
2014-03-25 15:05:11 -07:00
Pierre-Yves David
e46e61d8b1 bundle2: produce a bundle2 reply
We do not know yet what kind of data future features and extensions will need to
exchange. To handle that, bundle2 allows to send arbitrary content to the
server. As a consequence, we need to be able to reply arbitrary content to the
client. And, we can use bundle2 to transmit those arbitrary data.

When a client will push a bundle2 to the server, the server will reply with a
bundle2 itself.

This changeset installs the first stone of this logic and test it.
2014-04-04 14:24:11 -07:00
Pierre-Yves David
90cfb42a5c bundle2: add reply awareness to unbundlerecords
We need an efficient way to handle bundle replies. The unbundle records class is
extended to carry such data.
2014-04-11 08:24:59 -07:00
Pierre-Yves David
311fe283fd bundle2: add an integer id to part
For sending response to a pushed bundle, we need to link reply parts to request
part. We introduce a part id for this purpose. This is a 32 bit unique
integer stored in the header.
2014-04-01 00:07:17 -07:00
Pierre-Yves David
ece6aaecdb bundle2: make it possible have a global transaction for the unbundling
We use the `gettransaction` method approach already used for pull. We
need this because we do not know beforehand if the bundle needs a
transaction to be created. And (1) we do not want to create a
transaction for nothing. (2) Some bundle2 bundles may be read-only and
do not require any lock or transaction to be held.
2014-04-02 23:56:49 -07:00
Pierre-Yves David
11a11c0625 bundle2: first crude version of bundling changeset with bundle2
The current changegroup format is put in a "changegroup" part and processed by
an appropriate handlers.

This is not production ready code, but let us start smoke testing.
2014-03-24 19:37:59 -07:00
Pierre-Yves David
5ab0b5facf bundle2: record processing results in the bundleoperation object
Part handlers can now add records to the `bundleoperation` object. This can be
used to help other parts or to let the caller of the unbundling process react
to the results.
2014-04-02 22:37:50 -07:00
Pierre-Yves David
15e3869bad bundle2: introduce a bundleoperation object
This object will hold all data and state gathered through the processing of a
bundle. This will allow:

- each handler to be aware of the things unbundled so far
- the caller to retrieve data about the execution
- bear useful object and logic (like repo, transaction)
- bear possible bundle2 reply triggered by the unbundling.

For now the object is very simple but it will grow at the same time as the
bundle2 implementation.
2014-04-02 22:24:44 -07:00
Pierre-Yves David
ef32c25a27 bundle2: feed a unbundle20 to the processbundle function
The unbundle can comes from multiple sources. (on disk file, peer, etc) and
(ultimately) of multiple type (bundle10, bundle20). The `processbundle` is no
longer in charge of creating the bundle.
2014-04-02 13:50:57 -07:00
Pierre-Yves David
9e7aaa60ee bundle2: read the whole bundle from stream on abort
When the bundle processing abort on unknown mandatory parts, we now makes sure
all the bundle content is read. This avoid leaving the communication channel in
an unrecoverable state.
2014-03-24 17:20:15 -07:00
Pierre-Yves David
d0833349ae bundle2: add some distinction between mandatory and advisory part
Mandatory part cannot be ignored when unknown. We raise a simple KeyError
exception when this happen.

This is very early version of this logic, see inline comment for future
improvement lead.
2014-03-24 13:02:02 -07:00
Pierre-Yves David
074a113388 bundle2: introduce a parthandler decorator
Simple syntax sugar to register an handler for a new part type.
2014-03-24 15:51:00 -07:00
Pierre-Yves David
61eb0495c2 bundle2: first version of a bundle processing
We now have a function that interpret part content.

This is a version early version of this function. It'll see major changes in
scope and API in future development. As for previous I'm just focussing on
getting minimal logic setup. Refining will happen with real world usage.
2014-03-24 12:25:33 -07:00
Pierre-Yves David
6c017016a8 bundle2: safely read unpack data from part header
We use the same approach that the other unpack, as function is given the struct
format and his both responsible for reading the right amount of data from the
header and unpack the struct.

This give use flexibility if we decide to change the size of something in the
format before the release.
2014-04-01 00:08:15 -07:00
Pierre-Yves David
d9d35475e7 bundle2: part params 2014-03-20 01:24:45 -07:00
Pierre-Yves David
307f4468ab bundle2: support for bundling and unbundling payload
We add the ability to bundle and unbundle a payload in parts. The payload is the
actual binary data of the part. It is used to convey all the applicative data.
For now we stick to very simple implementation with all the data fit in single
chunk. This open the door to some bundle2 testing usage. This will be improved before
bundle2 get used for real. We need to be able to stream the payload in multiple
part to exchange any changegroup efficiently. This simple version will do for
now.

Bundling and unbundling are done in the same changeset because the test for
parts is less modular. However, the result is not too complex.
2014-03-19 23:36:15 -07:00
Pierre-Yves David
875acaf161 bundle2: support unbundling empty part
We augment the unbundler to make it able to unbundle the empty part we are now
able to bundle.
2014-03-19 23:04:03 -07:00
Pierre-Yves David
72d1282e60 bundle2: support bundling of empty part (with a type)
Here start the work on bundle2 parts. Our first step is to be able to bundle a simplistic
part that just have a type, no parameters, empty payload.
2014-03-18 14:29:33 -07:00
Pierre-Yves David
63355bceee bundle2: implement the mandatory/advisory logic for parameter
Parameter starting with an upper case are mandatory, the one starting with a
lower case are advisory and may be ignored.
2014-03-19 17:53:45 -07:00
Pierre-Yves David
335e57b78f bundle2: print debug information during unbundling
The unbundler class is now feed with an ui object and use it to transmit data
about the unbundling process.
2014-03-19 17:11:49 -07:00
Pierre-Yves David
9f528702b6 bundle2: print debug information during bundling
The bundler class is now feed with an ui object and use it to transmit data
about the bundling process.
2014-03-18 19:07:10 -07:00
Pierre-Yves David
8f763dcc63 bundle2: force the first char of parameter to be an letter.
We need a case sensitive character to convey mandatory/advisory parameter
semantic in a later patches.
2014-03-18 18:56:08 -07:00
Pierre-Yves David
8e900f2ca1 bundle2: refuse empty parameter name
The bundle2 now raise value error when seeing invalid parameter names. The first
introduced rules is: no empty parameter.

The test extension is improve to properly abort when ValueError are encountered.
2014-03-18 18:40:31 -07:00
Pierre-Yves David
dbf034c8a1 bundle2: urlunquote stream parameter name and value during unbundling
Align to new escaping used during bundling.
2014-03-18 17:43:08 -07:00
Pierre-Yves David
a54bdce8f6 bundle2: urlquote stream parameter name and value
This introduces support for arbitrary characters in stream parameters name and
value.  The urlquote format has been chosen because it is:

- simple,
- standard,
- no-op on simple alphanumerical entry.
2014-03-18 17:38:11 -07:00
Pierre-Yves David
246773194a bundle2: support for unbundling parameter value
The unbundler now understand parameter value. introduced in the previous
changeset.
2014-03-18 16:12:33 -07:00
Pierre-Yves David
51dbd8dd60 bundle2: support for bundling parameter value
Parameter can now have a value. We use a `<name>=<value>` form inspired from
capabilities.

There is still no kind of escaping in the name or value, yet.
2014-03-18 16:05:06 -07:00
Pierre-Yves David
6b98362873 bundle2: clarify stream parameter design in the documentation
Stream level parameter have very restricted use case. Clarify why we chosen a
textual format and point that applicative data goes in applicative parts.
2014-03-20 13:18:34 -07:00
Pierre-Yves David
c9ee8e68ae bundle2: support for unbundling simple parameter
the unbundler now understand simple list of parameter.
2014-03-18 15:56:24 -07:00
Pierre-Yves David
d7d49ad3b9 bundle2: support bundling simple parameter
This changeset add bundling capacity for simple parameters, not value or any
special case are handled.
2014-03-19 14:52:03 -07:00
Pierre-Yves David
0a30072db3 bundle2: make sure the unbundler refuse non bundle2 stream
We now make use of the magic string at the beginning of the file.
2014-03-18 16:35:34 -07:00
Pierre-Yves David
111c1061ba bundle2: a very first version of bundle2 unbundler
This changeset introduce an unbundler class to match the bundle2 bundler. It is
currently able to unbundle an empty bundle2 only and will gain more feature at
the same pace than the bundler.

It also comes with its special extension command in test.
2014-03-18 14:28:42 -07:00
Pierre-Yves David
b5e3ef023e bundle2: very first version of a bundle2 bundler
This changeset is the very first of a long series. It create a new bundle2
module and add a simple class that generate and empty bundle2 container.

The module is documented with the current state of the implementation. For
information about the final goal you may want to consult the mercurial wiki
page:

    http://mercurial.selenic.com/wiki/BundleFormat2

The documentation of the module will be updated with later patches adding more and
more feature to the format.

This patches also introduce a test case. This test case build and use its own
small extension that use the new bundle2 module. Since the new format is unable
to do anything right now, we could not use real mercurial code to test it.
Moreover, some advanced feature of the bundle2 spec will not be used by core
mercurial at all. So we need to have them tested.
2014-03-18 14:00:50 -07:00