Differences between revisions 10 and 11
Revision 10 as of 2009-05-19 19:31:01
Size: 3010
Editor: localhost
Comment: converted to 1.6 markup
Revision 11 as of 2009-09-20 21:55:43
Size: 2518
Editor: DavidSoria
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
The current implementation of the wire protcol in Mercurial lacks support to push and pull data that is not managed by the manifest and revlog. As a result extensions like the Bookmark Extension are not able to push their data over the wire. The following section will describe an approach to extend the wire protocol to make these usages possible. I think it is good to have a very strict wire protocol. This will make
it more robust and forward compatible. Also, the extension should not
break any existing code and should be 100% backward compatible.
Line 4: Line 6:
I propose to add a pushkey and listkeys method to the wire protocol. The pushkey can be used to push a key-value-pair to a remote repository. The remote repository can determine how to update the provided information. The listkeys method can be used to pull the information from a repository and update the data locally according to the provided information. == Idea ==
I suggest to add a mechanism to push and pull key-value-pairs of encoded
strings, e.g.: {'mybookmark': 'a3bc45a...'}.
The transfer encoding is utf-8. key-value-pairs are grouped into namespaces
to make it easier to distinguish bookmarks from other usages.

A 'pushkey' capable remote repository implements a pushkey()
call and a listkey() call. A call to listkey() returns a dictionary of
key-value-pairs matching a given namespace. A pushkey() call pushes a
given key-value-pair to the remote.

The logic to handle a pushed or pulled key is done by the code that uses
the key. In other words, bookmarks handle bookmark keys. This is needed
as for example bookmark might react in other ways to a --force than
ohter uses of pushkey. To keep the protocol strict it is not planned to
let extensions hook into the handling, meaning that all code dealing with
pushkey and listkey remain in mercurials core.

A new 'puskey' capability is added to check if source and remote support
the protocol extension.
Line 25: Line 46:
All keys are stored in a per-repo table. There are two possible implementations of the table. The first one would be a simple hash table that stores new elements before an existing element on a collision. This would give O(1) access to the last key, while still being able to retrieve older versions. In addition the hashtable allows to override existing entries. This would be useful for modules that do not need to store older revisions. An alternative to this approach is a hashlist that stores a list per hash entry that stores the acutal revisions. The second implementation would split revision controlled tables with non revision controlled tables in a collision aware hashtable and a hashtable set.

There decision to use just one storage is based on a stronger regulation that avoids errors and makes the pushkey/listkeys manageable for the core, while an implementation per module would add overhead and might lead to more performance impacts.

== Next Steps ==
Add the specifics of how you control who's allowed to push keys and how they're stored.

MartinGeisler suggests that we store the data in
{{{
.hg/keys/<handler>/<keyname>
}}}
files. We would then provide a function that can serialize/deserialize basic types, dicts, tuples, and lists.

The standard pickle module is probably not good since it's not safe on malicous data.
Unlike earlier suggestions, I think that storing key and values should
be done by the code that uses them. This means that bookmarks will still store
the bookmarks in .hg/bookmarks, ensuring backward compatibiltiy and
efficient storage. This is particularly useful if we want to use the
pushkey concept for example with localtags.

General

I think it is good to have a very strict wire protocol. This will make it more robust and forward compatible. Also, the extension should not break any existing code and should be 100% backward compatible.

Idea

I suggest to add a mechanism to push and pull key-value-pairs of encoded strings, e.g.: {'mybookmark': 'a3bc45a...'}. The transfer encoding is utf-8. key-value-pairs are grouped into namespaces to make it easier to distinguish bookmarks from other usages.

A 'pushkey' capable remote repository implements a pushkey() call and a listkey() call. A call to listkey() returns a dictionary of key-value-pairs matching a given namespace. A pushkey() call pushes a given key-value-pair to the remote.

The logic to handle a pushed or pulled key is done by the code that uses the key. In other words, bookmarks handle bookmark keys. This is needed as for example bookmark might react in other ways to a --force than ohter uses of pushkey. To keep the protocol strict it is not planned to let extensions hook into the handling, meaning that all code dealing with pushkey and listkey remain in mercurials core.

A new 'puskey' capability is added to check if source and remote support the protocol extension.

Implementation Details

The puskey/listkeys interfaces is defined as:

  boolean pushkey  (string identifier, string key, string value, boolean force=False)
  dict    listkeys (string identifier)

The identifier determines which handler to call on the remote site. A short example:

  pushkey('bookmarks', 'my-bookmark', 'aa3dfa...')

As a result the remote site knows to forward the information to the bookmark implementation. Pushkey returns falls if an error occurs during push.

Listkeys will return a key=>value combination. Both local and remote repository have to provide the necessary "capability" to be able to push and list keys.

Push Access

The current concept does not implement any special push/pull access rules. Everybody who has allow_push rights will be able to push keys. Listing of keys is always possible.

Storage

Unlike earlier suggestions, I think that storing key and values should be done by the code that uses them. This means that bookmarks will still store the bookmarks in .hg/bookmarks, ensuring backward compatibiltiy and efficient storage. This is particularly useful if we want to use the pushkey concept for example with localtags.


See also ArbitraryMetadata.

PushkeyConcept (last edited 2020-01-05 06:31:05 by MattHarbison)