Kinetic / kinetic-protocol

34 stars 21 forks source link

atomic multiupdate. #17

Open toolslive opened 10 years ago

toolslive commented 10 years ago

I'm not sure if this is the right place to ask, but the feature of an atomic multi-update would make people's lives a lot easier. (It's not for performance reasons, but for consistency reasons). Sometimes someone wants to update 2,3,... key value pairs together and not have to bother with partial failure of that operation (for example, trying to add a key and delete another at the same time).

The API can be (in python terms) illustrated by a small example:

...
client = kinetic.Client(...)
mu = client.makeMultiUpdate()

mu.addPut(key = ..., value=...., version=....,....)
mu.addPut(...)
mu.addDelete(key=,...., version=,....)
...

success = client.perform(mu)
if success: 
    ...

The api could be enriched with things like Asserts that allow early failure of the update, but that's not really needed.

Regarding backend implementation effort, obviously I don't know anything about the real devices, but on the simulator it's trivial to implement as leveldb provides all means necessary.

Note: the call could help the p2p api as well.

btw, Any eta on the 3.0 protocol version ?

jphughes commented 10 years ago

This is in progress.we sre currently going through some protocol cleanup, and this is already in the queue.

On Aug 29, 2014, at 12:59 AM, Romain Slootmaekers notifications@github.com wrote:

I'm not sure if this is the right place to ask, but I the feature of an atomic multi-update would make people's lives a lot easier. (It's not for performance reasons, but for consistency reasons). Sometimes someone wants to update 2,3,... key value pairs together and not have to bother with partial failure of that operation (for example, trying to add a key and delete another at the same time).

The API can be (in python terms) illustrated by a small example:

... client = kinetic.Client(...) mu = client.makeMultiUpdate()

mu.addPut(key = ..., value=...., version=....,....) mu.addPut(...) mu.addDelete(key=,...., version=,....) ...

success = client.perform(mu) if success: ... The api could be enriched with things like Asserts that allow early failure of the update, but that's not really needed.

Regarding backend implementation effort, obviously I don't know anything about the real devices, but on the simulator it's trivial to implement as leveldb provides all means necessary.

Note: One the call could help the p2p api as well.

btw, Any eta on the 3.0 protocol version ?

— Reply to this email directly or view it on GitHub.

barneywilliams commented 10 years ago

@toolslive,

Yes, I can see this being very handy for synchronization of multiple objects. This would make handling of aggregate objects which would likely involve dealing with Key Ranges (via GETKEYRANGE) much more sane... not to mention the nice/clean mapping to the LevelDB API.

jphughes commented 10 years ago

Hi:

The simulator will have this functionality soon. Specifically, the intention is to have


client.startBatch();
client.putAsync(...);
client.deleteAsync(...);
client.endBatch();

Anything in the batch other than async puts and deletes will result in errors. All the results will be sent back asynchronously after the endbatch. I suggest you can simulate this behavior by noop-ing the startbatch and endbatch.

toolslive commented 10 years ago

If I understand correctly: the putAsync (why is it called ...Async?) would throw a VersionMismatchException if the current for that key value is not what was expected, and all other subsequent updates in the batch would then be skipped? That could work. Do we have the guarantee that if something goes wrong before the kinetic drive processed the endBatch() correctly the whole batch acts as a noop ?

Also since you're still designing the api. It might be better to use an object based version:

batch = client.newBatch();
batch.put(...);
...
client.doBatch(batch)

The object based api cannot be used the wrong way while the imperative version can. (I'm thinking of session handling in the drive when the client does not call endBatch() or calls it twice, or starts multiple concurrent batches within the same connection, etc).